假设这两个辅助结构:
struct A { static constexpr bool Value = false; };
template <bool DEFERRED> struct B { static_assert(DEFERRED, "Failed"); };
以下使用它的课程:
class XYZ {
public:
template <class X = A, class Y = B<X::Value>> int SomeFunction() {...}
....
int main() {
XYZ xyz;
xyz.SomeFunction();
}
我不明白为什么不调用静态断言,因为模板boolean DEFERRED应该求值为false。但是,当我在函数体内实例化模板类型Y时,会调用静态断言。
有没有办法在不实例化模板类型Y的情况下触发static_assert评估? (或者更容易/更聪明的方式)
编辑:我应该提到我正在使用GCC 5.0
谢谢。
答案 0 :(得分:1)
您可以将一个类视为对象的蓝图,您可以将模板视为一个类的蓝图。
模板只是一个模板,在将模板实例化为类之前,它不是一个类,在声明xyz
变量之前,您不会这样做。
答案 1 :(得分:1)
因为模板布尔值DEFERRED应该评估为false(在您的问题中) ....
这是因为constexpr
中的struct A
。
constexpr
说明符可以在编译时评估bool
值
取出constexpr
并构建,你会发现差异。
为什么static_assert
无效:
static_assert
需要bool_constexpr
。
DEFERRED
只是bool,只有在实例化时才会在模板类体内知道该值。
尝试使用以下代码,我在bool constexpr
命名struct B
内添加了另一个test
。并将该变量传递给static_assert
。现在你的static_assert
正常工作。
//g++ 5.4.0
#include <iostream>
struct A { static constexpr bool Value = false; };
template <bool DEFERRED> struct B {
static constexpr bool test = false;
static_assert(test, "Failed");
};
class XYZ {
public:
template <class X = A, class Y = B<X::Value>> int SomeFunction()
{
return 0;
}
};
int main()
{
XYZ xyz;
xyz.SomeFunction();
}
你会注意到输出:
source_file.cpp:8:6: error: static assertion failed: Failed
static_assert(test, "Failed");
^
现在将test
中的struct B
值更改为true
。
它有效,没有错误。
还有另一种情况,将DEFERRED
分配给test
变量,如下所示:
template <bool DEFERRED> struct B {
static constexpr bool test = DEFERRED;
static_assert(test, "Failed");
};
上面说的static_assert
只有在main()实例化时才有效,如下所示。
B<false> b;
答案 2 :(得分:0)
我认为我的问题被误解了。我的问题是我期望编译器在实例化类型时评估主体,而不是在声明中使用它时。无论哪种方式,我通过执行以下操作解决了我的问题(使用样板代码):
template <bool DEFERRED> struct B {
static constexpr bool Proxy = DEFERRED;
static_assert(Proxy , "Failed");
};
template <class X = A, bool T = B<X::Value>::Proxy> int SomeFunction() {...}
这迫使编译器评估主体并触发任何静态断言。