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

Static assert template parameter check while creating an alias

假设我们有一个结构,我需要在其中检查模板参数的类型(wchar_t 只是一个示例):

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

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

Foo<int> foo;

但是如何防止编译:

using foo = Foo<int>;

?

当您尝试实际创建时它不会编译 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 只是引入了一个别名,它没有 "produce" 类型,所以下面是可能的:

#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>;不能自己编译。您需要一些机制来实际实例化模板。

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

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