【发布时间】:2013-07-25 12:08:36
【问题描述】:
这段代码演示了一个使用模板的编译时断言。 我发现它只能由g++(4.4.7)使用以下cmd行编译。
$ g++ -std=c++98 a.cpp -o a
Nether icc (13.0.1) 和 visual c++ (14.00.50727.762 for 80x86) 都可以编译它。对于icc,它会生成这样的错误消息
$ icpc a.cpp -o a
a.cpp(13): error: non-integral operation not allowed in nontype template argument
COMPILE_TIME_ASSERT(true && "err msg");
^
a.cpp(13): error: class "CompileTimeAssert<<error-constant>>" has no member "Check"
COMPILE_TIME_ASSERT(true && "err msg");
^
compilation aborted for a.cpp (code 2)
但是我发现像true && "err msg" 这样的断言在运行时断言中被广泛使用为Add custom messages in assert?
问题是
- 是否可以在不修改代码的情况下仅使用适当的编译选项来解决此问题?
- 如果不能,是否可以使用自定义消息进行编译时断言的替代方法?
演示代码如下。
#include <iostream>
template<bool B> class CompileTimeAssert { };
template<> class CompileTimeAssert<true> {
public:
static inline void Check() { }
};
#define COMPILE_TIME_ASSERT(b) CompileTimeAssert<(b)>::Check()
int main()
{
COMPILE_TIME_ASSERT(true && "err msg");
std::cout<<(true && "err msg")<<std::endl;
return 0;
}
【问题讨论】:
-
你一定要使用std=c++98标准吗?
-
@YochaiTimmer 不,我只是想证明 g++ 即使使用该选项也可以编译代码
-
对于非类型模板参数,只有整数参数是合法的。
-
@Eric 那你为什么不直接使用 static_assert (C++0x & C++11)
-
我从未将这种方法用于静态断言(我使用了
typedef char assert_XXX[(condition?1:-1)];),但您可以考虑更改宏以便将字符串传递给函数:COMPILE_TIME_ASSERT(condition,"Message")将扩展为CompileTimeAssert<(condition)>::Check("Message")修改签名后可能更容易被所有编译器消化
标签: c++ templates visual-c++ gcc icc