C++11 带有部分模板专门化的静态断言 模板 结构S{/*static_assert(0,“类型不受支持”);*/}; 模板 结构{ void foo(){} }; ... S i; i、 foo(); sd; //d.foo();

C++11 带有部分模板专门化的静态断言 模板 结构S{/*static_assert(0,“类型不受支持”);*/}; 模板 结构{ void foo(){} }; ... S i; i、 foo(); sd; //d.foo();,c++11,template-specialization,static-assert,C++11,Template Specialization,Static Assert,我希望在int的情况下永远不会实例化“主模板”,但如果我取消对静态断言的注释,则S实例化将失败。即使是一个单独的typedefsi将无法编译。(通用条款4.9.2 Cygwin) 我的目标不是让S在foo()调用中失败,而是在模板本身的实例化中失败,并且出现有意义的错误消息。我知道我可以做类似于typename T::nonexistent\u type T将阻止模板进行编译,但这不如静态断言消息。(注意:将static_assert放入主模板中的函数定义中仍然无法编译S) 为什么即使没有实例化

我希望在
int
的情况下永远不会实例化“主模板”,但如果我取消对
静态断言的注释,则
S
实例化将失败。即使是一个单独的
typedefsi将无法编译。(通用条款4.9.2 Cygwin)

我的目标不是让
S
foo()
调用中失败,而是在模板本身的实例化中失败,并且出现有意义的错误消息。我知道我可以做类似于
typename T::nonexistent\u type T将阻止模板进行编译,但这不如
静态断言
消息。(注意:将
static_assert
放入主模板中的函数定义中仍然无法编译
S


为什么即使没有实例化模板,
static\u assert
也会失败?该标准是否强制要求(或“未指定”)执行此操作?有没有一种方法可以像我希望的那样使用
static\u assert
失败?

如果希望仅实例化时间,则
static\u assert
中的表达式必须依赖于模板参数。这是由标准保证的-实现可以(但没有义务)检查不依赖于任何模板参数的模板中的
静态\u断言

您的代码是一种奇怪的迂回方式

template<typename T, typename U = void>
struct S { /* static_assert(0, "type unsupported"); */ };
template<typename T>
struct S<T, typename std::enable_if<std::is_integral<T>::value, void>::type> {
    void foo() {}
};
...
S<int> i;
i.foo();
S<double> d;
// d.foo();
模板结构{
静态_断言(std::is_integral::value,“类型不受支持”);
void foo(){}
};

这清楚地向编译器传达了表达式和模板参数之间的依赖关系,并且更清晰、更易于阅读。实际上,我不太清楚您是希望整型编译失败还是非整型编译失败。

请看,我已经将原来的问题简化为最简单的问题来演示这个问题。我需要在编译时识别各种情况,而其他任何情况都会失败,这是许多局部专门化所无法匹配的。因此,上面的代码。我刚刚意识到,对类型的任何依赖都是足够的:
static\u assert
满足了我的需求。(几乎--
typedef的Sd
仍在编译,但是
Sd
声明失败,所以这很正常)@lrfy:那么最简单的事情就是创建一个
is\u valid
特性,它结合了各种部分专门化情况,并将其用作conditional@Puppy-我自己也有过类似的经历。您的
是有效的
解决方案有时意味着编写两个模板,两个模板都具有所有的专门化,而不仅仅是一个,并且纯粹是为了从您真正想要的模板中获得更好的错误消息。这可能有点混乱,重复所有的专门化案例意味着它们很容易不一致(尽管AFAICT永远不会导致运行时错误)。奇怪地编写
static\u assert
条件可能是一种更好的方法,而且可能值得使用
dependent\u false
模板。
template<typename T> struct S {
    static_assert(std::is_integral<T>::value, "type unsupported");
    void foo() {}
};