如果我在模板化的类中有一个函数insert
,我会重载它以采用填充模式:
void insert(const size_type N, const value_type &element);
或范围模式:
template <class iterator_type>
void insert(const iterator_type begin, const iterator_type end)
当我将类的value_type
指定为int时,会导致以下调用:
insert(500, 50);
不明确,因为它假定500
为int
因此不匹配size_type N
,而不是调用填充模式函数,而是调用模板化范围函数并失败
这是一个与C ++ 03兼容的库,它不能使用像boost这样的外部库,只能使用内置的C ++代码。我发现并不需要C ++ 11 enable_if
的唯一解决方法是创建额外的重载,将size_type
替换为int
,{{ 1}},long int
等,并从中调用fill函数。显然这是有问题的,因为你可以拥有与char
匹配的许多不同类型。有什么建议吗?
答案 0 :(得分:3)
利用SFINAE:
void insert(const size_type N, const value_type &element);
template <class iterator_type>
void insert(iterator_type begin, iterator_type end, char (*)[sizeof(*begin)] = NULL);
编译器将优化范围版本insert
中的额外伪参数。它的唯一作用是消除模板函数,使其不能用于解除引用运算符的类型的重载分辨率。
澄清诀窍:
char (*)[sizeof(*begin)]
代表指向大小等于sizeof(*begin)
的字符数组的指针。如果变量begin
不可解除引用,那么这将是一个错误。但是,在函数重载解析期间考虑函数模板的情况下,这样的错误不会停止编译,而只是丢弃模板(替换失败不是错误 - SFINAE)。
答案 1 :(得分:0)
根据您支持的确切编译器,您可能会发现enable_if是内置的 - 它在TR1中存在。
然而,enable_if的实现是微不足道的。你也可以简单地从Boost复制它。事实上,它很短暂,我将在这个答案中发布它。
namespace boost
{
template <bool B, class T = void>
struct enable_if_c {
typedef T type;
};
template <class T>
struct enable_if_c<false, T> {};
template <class Cond, class T = void>
struct enable_if : public enable_if_c<Cond::value, T> {};
template <bool B, class T>
struct lazy_enable_if_c {
typedef typename T::type type;
};
template <class T>
struct lazy_enable_if_c<false, T> {};
template <class Cond, class T>
struct lazy_enable_if : public lazy_enable_if_c<Cond::value, T> {};
template <bool B, class T = void>
struct disable_if_c {
typedef T type;
};
template <class T>
struct disable_if_c<true, T> {};
template <class Cond, class T = void>
struct disable_if : public disable_if_c<Cond::value, T> {};
template <bool B, class T>
struct lazy_disable_if_c {
typedef typename T::type type;
};
template <class T>
struct lazy_disable_if_c<true, T> {};
template <class Cond, class T>
struct lazy_disable_if : public lazy_disable_if_c<Cond::value, T> {};
} // namespace boost
答案 2 :(得分:0)
在Puppy的帮助下,答案明白了:
// Fill insert
void insert(const size_type N, const value_type &element);
// Enable_if template
template <bool condition, class T = void>
struct enable_if_c
{
typedef T type;
};
template <class T>
struct enable_if_c<false, T>
{};
// Range insert:
template <class iterator_type>
iterator insert (const typename enable_if_c<!std::numeric_limits<iterator_type>::is_integer, iterator_type>::type &first, const iterator_type &last);
numeric_limits是C ++ 03安全的,适用于包括MSVC 2010在内的所有(测试)编译器。这将检查以确保提供给range-insert的类型不是整数。