实例化特定模板专业化时断言

时间:2014-04-21 22:27:15

标签: c++ templates c++11 static-assert

可以编写一个模板,该模板被设计为由用户明确专门化,在默认模板上添加一些有用的错误消息:

template<typename T>
struct foo
{
    static_assert( sizeof(T) != sizeof(T) , "Please specialize foo for your type" );
};

由于always-false条件取决于模板参数,因此对该断言的评估将仅在模板即时期间完成,正是我们想要的。

现在考虑相反的情况:我们允许用户使用模板的通用版本,但不允许他使用特定的即时消息。例如:

template<typename T>
struct bar
{
    /* something useful for the user */
};

template<>
struct bar<char>
{
    static_assert( false , "No, you can't instantiate bar with char" );
};

当然这不起作用,因为断言不依赖于模板参数,即使用户没有实例化bar<char>,编译也会失败。

我的问题是:在模板即时化之前,有没有办法推迟对那种断言表达式的评估?

编辑:一个更复杂的例子:

template<typename T>
struct quux
{
    /* something useful for the user */
};

/* This specialization is defined to reject any instance of quux which uses a 
 * template with bool as parameter 
 */
template<template<typename> class T>
struct quux<T<bool>>
{
    static_assert( false , 
                   "Please don't use quux with a template with a bool parameter" );
};

2 个答案:

答案 0 :(得分:4)

无需单独专业化:

template<typename T>
struct bar
{
    static_assert( !std::is_same<T, char>::value,
        "No, you can't instantiate bar with char" );
};

编辑:为了回应您的编辑,再次类似的事情:

template<template<typename> class T, typename U>
struct quux<T<U>>
{
    static_assert( !std::is_same<U, bool>::value , 
                   "Please don't use quux with a template with a bool parameter" );
};

答案 1 :(得分:1)

您可以添加另一个虚拟模板参数:

#include <type_traits>

template<typename T,typename=void>
struct bar
{
    /* something useful for the user */
};

template<typename U>
struct bar<char,U>
{
    static_assert( std::is_same<U,void>::value && false, "No, you can't instantiate bar with char" );
};

int main()
{
    bar<int> b;
}