Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/asp.net-core/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 在C+中声明对象和使用typedef的顺序+;_C++_Typedef_Declaration_Predicate - Fatal编程技术网

C++ 在C+中声明对象和使用typedef的顺序+;

C++ 在C+中声明对象和使用typedef的顺序+;,c++,typedef,declaration,predicate,C++,Typedef,Declaration,Predicate,考虑类a、STL容器B和容器的二进制谓词C 容器B用于类A,但类A也用于二进制谓词C struct C{ bool operator()(A const &a, A const &b){ return a.compare_variable < b.compare_variable; } }; 申报A、B和C的正确顺序是什么 我尝试了以下顺序的变化: 首先声明类A,然后是结构C,最后是类型定义,我得到一个错误:container1,container2没有

考虑类a、STL容器B和容器的二进制谓词C

容器B用于类A,但类A也用于二进制谓词C

struct C{
  bool operator()(A const &a, A const &b){
    return a.compare_variable < b.compare_variable;
  }
};
申报A、B和C的正确顺序是什么

我尝试了以下顺序的变化:

  • 首先声明类A,然后是结构C,最后是类型定义,我得到一个错误:container1,container2没有命名一个类型——类型在声明类时不存在

  • 首先是typedef:大量错误——类和结构都还没有定义

  • 首先声明类,并将typedef放在public:struct部分:一个错误,指出第三个模板参数(C)无效——它尚未定义
  • 首先声明struct:error,表示类尚未定义

我使用的方法是否不必要的麻烦,是否存在更优雅的解决方案?

那么您想要这样的解决方案吗

class A {
  struct C{
    bool operator()(A const &, A const &);
  };
  typedef B<A, vector<A>, C> type;
  type c1, c2;

public:
  int compare_variable; // ?
};
// the definition below should either go in a .cpp file,
// or you should mark it inline
bool A::C::operator()(A const &x, A const &y) {
  return x.compare_variable < y.compare_variable;
}
A类{
结构C{
布尔运算符()(常数&,常数&);
};
B型;
c1、c2型;
公众:
int比较_变量;/?
};
//下面的定义应该放在.cpp文件中,
//或者您应该将其标记为内联
bool A::C::operator()(常数&x,常数&y){
返回x.compare\u变量
重要注意事项:从技术上讲,标准库容器如
std::vector
。用不完整的类型实例化它们是未定义的行为。类型
A
A
的定义中是不完整的,这意味着您不能可靠地使用
std::vector类型的成员,该成员保证支持不完整的类型

下面的讨论假设
B
vector
支持不完整类型的实例化。
如果它们不支持,则不可能完成您尝试执行的操作


首先,找出依赖关系:

struct C {
  bool operator()(A const &a, A const &b){
    return a.compare_variable < b.compare_variable;
  }
};
定义
类型
只需要向前声明
A
向量
B
、和
C
。typedef本身不会触发模板的实例化

class A{
public:
    type container1, container2;
};
这会触发
B
的实例化,需要
B
的完整定义。容器也可能需要比较器
C
,作为一个完整的类型,因为它们需要存储它的副本

因此,简言之:

  • 定义
    C
    需要向前声明
    a
    。定义
    C::operator()
    需要
    A
    的完整定义
  • 定义
    类型
    需要向前声明
    A
    B
    C
  • 定义
    A
    需要
    B
    C
    的完整定义
整理完依赖项后,就可以编写代码了。假设
B
是通过包含适当的标题来定义的:

class A;     // Forward declare A for C's definition
struct C {
  bool operator()(A const &a, A const &b);
};

typedef B<A, vector<A>, C> type;

class A{
public:
    type container1, container2;
};

inline bool C::operator()(A const &a, A const &b){
  return a.compare_variable < b.compare_variable;
}
A类;//为C的定义前向声明A
结构C{
布尔运算符()(常数A、常数b);
};
B型;
甲级{
公众:
集装箱1型、集装箱2型;
};
内联布尔C::运算符()(常数A、常数b){
返回a.compare\u变量

请注意,显然,您需要在a中实际创建一个
compare\u变量
成员。

bool operator()定义中有一个打字错误,它应该是
bool operator()(常数&a,常数&b){…
So
inline
用于替换每个调用站点的函数代码。这对于比较操作来说是有意义的。但是,是否还有其他类型的函数需要
inline
?@MusséRedi
inline
说明符基本上允许您将函数定义放在头中没有得到链接器错误的文件。现在的编译器通常自行决定是否实际内联函数。请注意,在类定义中定义的任何函数(如原始
C
中的
operator()
)隐式地
内联
。由于我们将函数定义移到类定义之外,因此需要使
内联
显式(或在cpp文件而不是标头中定义它)。在这种情况下,首选的约定是什么?对我来说,在类中包含比较谓词C似乎更符合逻辑,也更优雅,就像您所做的那样,而不是将其声明为单独的结构。如果它在逻辑上绑定到类,请将其放在其中。如果您可能合理地重复使用它,请将其放在外部。
typedef B<A, vector<A>, C> type;
class A{
public:
    type container1, container2;
};
class A;     // Forward declare A for C's definition
struct C {
  bool operator()(A const &a, A const &b);
};

typedef B<A, vector<A>, C> type;

class A{
public:
    type container1, container2;
};

inline bool C::operator()(A const &a, A const &b){
  return a.compare_variable < b.compare_variable;
}