创建别名时静态断言模板参数检查

时间:2015-12-08 09:28:30

标签: c++ templates c++11 typetraits c++17

让我们说我们需要检查模板参数类型的结构(wchar_t只是一个例子):

template <typename T>
struct Foo {
    static_assert(std::is_same<T, wchar_t>::value, "Failure");
}

当然下面的代码不会编译:

Foo<int> foo;

但是如何防止编译:

using foo = Foo<int>;

2 个答案:

答案 0 :(得分:4)

如果您真的想在第using FooINT = Foo<int>;行上产生错误,可以使用默认模板参数:

template <
    typename T,
    typename = std::enable_if_t<std::is_same<T, wchar_t>::value>
>
struct Foo { };

答案 1 :(得分:2)

当您尝试实际创建foo时,它将无法编译?一旦变量成为变量,就改变foo的含义。

#include <iostream>
using namespace std;

template <typename T>
struct Foo {
    static_assert(std::is_same<T, wchar_t>::value, "Failure");
};

using FooINT = Foo<int>;

int main() {
    FooINT foo; // breaks
    return 0;
}

所以你基本上定义了一个没用的类型别名。不幸的是,创建特定的别名不会导致立即实例化该类型。

详细说明一下。 using只是引入了一个别名,它不会“生成”该类型,因此以下内容是可能的:

#include <iostream>
using namespace std;

template <typename T>
struct Foo {
    static_assert(std::is_same<T, wchar_t>::value, "Failure");
};

using FooINT = Foo<int>; // should it break now or not?

template <>
struct Foo<int> {
    int A_OK;
};

int main() {
    FooINT foo; // works now
    return 0;
}

所以你不能让using FooINT = Foo<int>;不能自己编译。您需要一些机制来实际实例化模板。