【问题标题】:Static assert template parameter check while creating an alias创建别名时静态断言模板参数检查
【发布时间】:2015-12-08 09:28:29
【问题描述】:

假设我们有需要检查模板参数类型的结构(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(类型别名),也是一样的。只要您不实例化它,编译器就不会“生成”代码并且不会检查断言。

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


【解决方案1】:

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

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

【讨论】:

    【解决方案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&lt;int&gt;; 不能自己编译。您需要一些机制来实际实例化模板。

    【讨论】:

    • 谢谢。也许我不够具体,因为我想要达到的目的是防止仅使用 foo = Foo; 进行编译没有先前的实例化。但由于你所说的,这是不可能的。
    • 是的,我添加了一个示例,它显示了如果您的建议有效,什么是不可能的或令人困惑的。这可能是为什么 alias 只是一个别名,并没有做更多的事情,除了可能出于性能原因。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-11-05
    • 2011-08-28
    • 1970-01-01
    相关资源
    最近更新 更多