有没有办法强制用户显式指定模板参数类型?

时间:2015-01-27 13:19:32

标签: c++ templates

简短版本:我有一个模板函数,它是“通用的”,但是我想强制用户显式指定参数的类型,它们作为参数传递给这个函数。

有什么想法吗?


长版本:听起来像一个糟糕的设计,但这是我的情况,我现在想不出更好的东西。

我正在尝试在一个小::setsockopt类中“实现”socket(我不想拥有大量的函数,使用不同的参数并做同样的事情)。例如:

template< typename OPTION_VALUE_TYPE >
bool set_option( int level, int option_name, const OPTION_VALUE_TYPE& value )
{
    return -1 != ::setsockopt( fd_, level, option_name, &value, sizeof( value ) );
}

但是,这可能会导致以下情况 - 使用set_option调用1,尝试设置unsigned char选项会导致失败,因为1是{{1} }}。正确的用法是:

int

作为

set_option< unsigned char >( level, option, 1 );

编译得非常好,但是会非常错误。

2 个答案:

答案 0 :(得分:5)

是的,您只需要以不能从参数推导出的方式使用模板参数。一种常见的方法是在模板类中使用typedef:

template <typename T>
struct identity {
  typedef T type;
};

template <typename OPTION_VALUE_TYPE>
bool set_option(int level, int option_name,
                typename identity<const OPTION_VALUE_TYPE&>::type value);

要使用标准库中已有的类型,您可以使用enable_if

template <typename OPTION_VALUE_TYPE>
bool set_option(int level, int option_name,
                typename std::enable_if<true, const OPTION_VALUE_TYPE&>::type value);

这不允许类型参数推断的原因是因为编译器不能排除identity的特化:编译器不能排除你的行为

template <>
struct identity<U> { typedef V type; };

identity<U>::type不再是U

答案 1 :(得分:4)

将模板类型放在非推导的上下文中,如下所示:

template <typename T> struct identity { using type = T; };

template <typename OPTION_VALUE_TYPE>
bool set_option(int level,
                int option_name,
                const typename identity<OPTION_VALUE_TYPE>::type& value);