禁止特定的函数模板实例化

时间:2011-04-22 10:49:24

标签: c++

我想定义一个模板函数,但不允许使用特定类型进行实例化。请注意,通常允许所有类型和通用模板工作,我只想禁止使用一些特定类型。

例如,在下面的代码中,我希望阻止将double与模板一起使用。这实际上并不会阻止实例化,但只是因为没有定义函数而导致链接器错误。

template<typename T>
T convert( char const * in )
{ return T(); }

//this way creates a linker error
template<>
double convert<double>( char const * in );

int main()
{
    char const * str = "1234";

    int a = convert<int>( str );
    double b = convert<double>( str );
}

代码只是一个演示,显然转换函数必须做更多的事情。

问题:在上面的代码中,如何在尝试使用convert<double>实例化时产生编译器错误?


我能找到的最近的相关问题是How to intentionally cause a compile-time error on template instantiation它处理的是一个类,而不是一个函数。

我需要这样做的原因是因为我希望阻止的类型实际上会编译并使用通用版本执行某些操作。但是,这不应该是函数合同的一部分,并且可能不会在所有平台/编译器和未来版本中受支持。因此,我想完全避免使用它。

4 个答案:

答案 0 :(得分:3)

我会在函数调用中使用静态断言来在函数实例化期间创建正确的失败:

template<typename T>
class is_double{ static const int value = false; }

template<>
class is_double<double>{ static const int value = true; }

template<typename T>
T convert( const char *argument ){
    BOOST_STATIC_ASSERT( !is_double<T>::value );
    //rest of code
}

这应该在一个函数中起作用。

答案 1 :(得分:1)

您可以使用仿函数代替函数:

template<typename T>
struct convert { 
    T operator()(char const * in) const { return T(); } 
};
template<> struct convert<double>;

int main()
{
    char const * str = "1234";

    int a = convert<int>()( str );
    double b = convert<double>()( str ); // error in this line

    return 0;
}

这会在实例化时给你一个错误。

通过添加辅助函数,您将获得所需的行为:

template<typename T>
struct convert_helper { 
    T operator()(char const * in) const { return T(); } 
};
template<> struct convert_helper<double>;

template<typename T>
T convert( char const * in ) { return convert_helper<T>()( in ); }

int main()
{
    char const * str = "1234";

    int a = convert<int>( str );
    double b = convert<double>( str );

    return 0;
}

答案 2 :(得分:1)

如果您不想依赖static_assert或使代码在C ++ 0x之前移植,请使用:

template<class T>
void func(){
    typedef char ERROR_in_the_matrix[std::is_same<T,double>::value? -1 : 1];
}

int main(){
  func<int>(); // no error
  func<double>(); // error: negative subscript
}

答案 3 :(得分:0)

考虑Boost disable_ifBoost TypeTraits

查看How can I write a function template for all types with a particular type trait?

这是一个例子:

#include <boost/type_traits.hpp>
#include <boost/utility/enable_if.hpp>

template<typename T>
T convert( char const * in, 
           typename boost::disable_if<boost::is_floating_point<T>, T>::type* = 0 )
{ return T(); }


int main()
{
    char const * str = "1234";

    int a = convert<int>( str );
    double b = convert<double>( str );
    return 0;
}


这是字符串

的编译错误
double b = convert<double>( str );
  

1&gt;。\ simple_no_stlport.cpp(14):错误   C2770:显式模板无效   'T convert(const char。)的参数   *,升压:: disable_if,T&GT; ::类型   *)'1&gt; 。\ simple_no_stlport.cpp(5):看   声明'转换'