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

Static assert template parameter check while creating an alias

本文关键字:参数 检查 断言 别名 静态 创建      更新时间:2023-10-16

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

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

当然,以下代码不会编译:

Foo<int> foo;

但是我如何阻止编译:

using foo = Foo<int>;

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

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

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