我在basic_buffer
类上有以下方法声明:
const_iterator insert(const_iterator position, typename argument<value_type>::type val)
请注意第二个参数的类型。我经常使用这种argument
特征,这些特征基本上决定了在接收模板参数时应该通过复制还是引用传递参数。在这种情况下,value_type
是模板参数T
的typedef
。例如,基本类型应该通过复制而不是常量引用传递。下面是实现:
template <typename T> struct argument
{
typedef std::conditional<std::is_fundamental<T>::value || std::is_pointer<T>::value, const T, const T &> type;
};
请注意基本类型和指针类型的计算结果如何const T
,其他类型的计算结果如何计算为 const T &
。到目前为止,这一直运作良好。
现在考虑以下函数:
template <class T>
void foo()
{
typedef basic_buffer<T> _storage_type;
typedef typename _storage_type::value_type _value_type;
_value_type value = 0;
_storage_type _storage;
_storage.insert(_storage.end(), value);
}
省略了几个细节。这就是我得到的:
error: no matching member function for call to 'insert'
_storage.insert(_storage.end(), value);
~~~~~~~~~^~~~~~
令我惊讶的是这个重载版本不匹配:
note: candidate function not viable: no known conversion from '_value_type' (aka 'unsigned char') to 'typename argument<value_type>::type' (aka 'conditional<std::is_fundamental<unsigned
char>::value || std::is_pointer<unsigned char>::value, const unsigned char, const unsigned char &>') for 2nd argument
const_iterator insert(const_iterator position, typename argument<value_type>::type val)
更令人困惑的是,如果我value
投_value_type
(值得注意的是,这已经是它的类型),它可以工作:
_storage.insert(_storage.end(), static_cast<_value_type>(value));
所以我可以通过投value
来解决这个问题,但不是。这是怎么回事?
你有
typedef std::conditional<std::is_fundamental<T>::value || std::is_pointer<T>::value, const T, const T &> type;
所以类型是一个std::conditional<std::is_fundamental<T>::value || std::is_pointer<T>::value, const T, const T &>
当您致电时
_storage.insert(_storage.end(), value);
它试图将value
转换为std::conditional<std::is_fundamental<T>::value || std::is_pointer<T>::value, const T, const T &>
您需要向条件添加::type
才能从条件中获取结果类型。
typedef std::conditional<std::is_fundamental<T>::value || std::is_pointer<T>::value, const T, const T &>::type type;