2017-04-10 49 views
1

假设这两个辅助结构:静态断言不叫

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(); 
} 

我不明白为什么静态断言不叫因为模板布尔DEFERRED应该计算为false。但是,当我在函数体内实例化模板类型Y时,将调用静态断言。

有没有办法在不实例化模板类型Y的情况下触发static_assert评估? (或者更简单/更聪明的方式)

编辑:我应该提到我使用GCC 5.0

谢谢。

+0

“Static_assert”是编译时断言。它有效当你有本地bool_constexpr。下面添加了一些测试代码。 – Naidu

回答

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() {...} 

这迫使编译器来评估身体和触发任何静态断言。

1

你可以看到一个类作为一个对象的蓝图,你可以看到一个模板作为一个类的蓝图。

模板只是一个模板,它不是一个类,直到您将模板实例化到一个类中,而您在变量xyz的声明之前不会这样做。

+0

我的印象是,当类类型被模板实例化时(编译器会传播并“替换”模板参数,然后执行任何浮动static_assert(s))。不是在变量实例化中使用类型时。 –

1

,因为模板布尔递延应该评估为假(你的问题) ....

这是因为在struct Aconstexpr的。

constexpr符能够在编译时评估bool

取出constexpr而建,你会发现其中的差别。

为什么你static_assert不工作:

static_assert期望一个bool_constexpr

DEFERRED只是bool,只有在我们实例化时,模板类体内的值才是已知的。

尝试使用以下代码,我在struct B的内部添加了另一个bool constexpr,命名为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"); 
    ^

现在struct Btest值更改为true

它的工作原理,没有错误。

还有另外一种情况,分配给DEFERRED可变test如下图所示:

template <bool DEFERRED> struct B { 
    static constexpr bool test = DEFERRED; 
    static_assert(test, "Failed"); 
}; 

上面说的只是static_assert的作品,如果你在实例化的main(),像下面。

B<false> b;