编译时断言不可靠? 我将通过《现代C++设计》的第一章。特别是编译时断言。我对以下代码有一些问题: template<bool> struct CompileTimeChecker { CompileTimeChecker(...) {} }; template<> struct CompileTimeChecker<false> {}; #define STATIC_CHECK(expr, msg)\ {\ struct ERROR_##msg {ERROR_##msg() {}};\ CompileTimeChecker<((expr) != 0)>(ERROR_##msg());\ } int main() { STATIC_CHECK(0, MessageNull); STATIC_CHECK(1, MessageOne); } 模板结构编译器 { CompileTimeChecker(…){} }; 模板结构CompileTimeChecker{}; #定义静态检查(expr,msg)\ {\ 结构错误35;#msg{ERROR 35;#msg(){}\ CompileTimeChecker(ERROR####msg())\ } int main() { 静态检查(0,MessageNull); 静态检查(1,MessageOne); }

编译时断言不可靠? 我将通过《现代C++设计》的第一章。特别是编译时断言。我对以下代码有一些问题: template<bool> struct CompileTimeChecker { CompileTimeChecker(...) {} }; template<> struct CompileTimeChecker<false> {}; #define STATIC_CHECK(expr, msg)\ {\ struct ERROR_##msg {ERROR_##msg() {}};\ CompileTimeChecker<((expr) != 0)>(ERROR_##msg());\ } int main() { STATIC_CHECK(0, MessageNull); STATIC_CHECK(1, MessageOne); } 模板结构编译器 { CompileTimeChecker(…){} }; 模板结构CompileTimeChecker{}; #定义静态检查(expr,msg)\ {\ 结构错误35;#msg{ERROR 35;#msg(){}\ CompileTimeChecker(ERROR####msg())\ } int main() { 静态检查(0,MessageNull); 静态检查(1,MessageOne); },c++,static-assert,C++,Static Assert,这不会引起g++7.4.0和clang++6.0.0的编译时错误。但是,以下代码确实会引发错误(如预期的那样): 模板结构编译器 { CompileTimeChecker(…){} }; 模板结构CompileTimeChecker{}; #定义静态检查(expr,msg)\ {\ 结构错误消息{错误消息{i;}\ CompileTimeChecker(错误消息(0))\ } int main() { 静态检查(0,MessageNull); 静态检查(1,MessageOne); } 第二段

这不会引起g++7.4.0和clang++6.0.0的编译时错误。但是,以下代码确实会引发错误(如预期的那样):

模板结构编译器
{
CompileTimeChecker(…){}
};
模板结构CompileTimeChecker{};
#定义静态检查(expr,msg)\
{\
结构错误消息{错误消息{i;}\
CompileTimeChecker(错误消息(0))\
}
int main()
{
静态检查(0,MessageNull);
静态检查(1,MessageOne);
}
第二段代码中唯一的区别是使用带参数的构造函数


在这两种情况下,预期的错误消息为:

  • g++:
    调用“CompileTimeChecker::CompileTimeChecker(main()::ERROR\u MessageNull)”时没有匹配的函数。
  • clang++:
    没有从'ERROR\u MessageNull'转换为'CompileTimeChecker'的函数样式的匹配转换。
    • 这被称为最烦人的解析。声明如下:

      CompileTimeChecker<expr>(Type());
      
      这样,就不能将其解释为声明。您还可以使用自C++11以来的
      {}
      初始化。另一方面,

      CompileTimeChecker<expr>(Type(0));
      
      CompileTimeChecker(类型(0));
      
      是一个表达式语句,它根据需要创建对象,因为
      Type(0)
      不可能声明函数


      <> P> C++ C++ 11,只使用<代码> StistalyAsSt>。< /P>为什么不呢?也应该是<代码> CopyLeTeMeCuqKue/Cuth>,而不是<代码> CopyLeTeMeCuqKue/Cuff>,因为这是宏。@ Yksisarvinen:主要是因为“现代C++设计”不再是现代的。它早于C++11和
      static_assert
      。是的,而且它还特别允许在同一范围内有一个具有相同名称的结构和函数,以与C兼容。括号没有为我修复它,因为
      function((a))
      等于
      function(a)
      。但是关于函数/构造函数的模糊性,您是对的。编写
      CompileTimeChecker(类型{})为我修复了它(即使用统一初始化)。你能更新你的答案吗?@L.F.
      CompileTimeChecker((Type())不适合我。@图像我错了。我把这个例子和另一个最令人烦恼的例子混淆了。我已经更新了答案。希望不会再让我们烦恼了!
      
      CompileTimeChecker<expr> Type();
      
      CompileTimeChecker<expr> var = Type();
      
      CompileTimeChecker<expr>(Type(0));