2016-02-17 3 views
1

У меня метод следующее объявление на basic_buffer класса:не соответствующие функции члена для вызова «вставки»

const_iterator insert(const_iterator position, typename argument<value_type>::type val) 

Обратите внимание на тип второго аргумента. Я часто использую эти argument черты, которые в основном решают, должен ли аргумент передаваться копией или ссылкой при получении аргументов шаблона. В этом случае value_type является typedef аргумента шаблона T. Например, фундаментальные типы должны быть переданы копией вместо ссылки на константу. Вот реализация:

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, а не. Что здесь происходит?

ответ

3

Вы

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; 
+0

Конечно! Как я пропустил это :) как ни странно, теперь у меня такая же проблема с '_storage.insert (_storage.end(), value | carry)', которую я раньше не делал, из-за типа возвращаемого побитового оператора. Забавно, что компилятор был способен вывести один тип, а не другой, но это уже имеет смысл при решении задачи. Благодаря! –

+0

Собственно, актер не работает! –

+0

@ AndréFratelli Что такое 'value' и' carry' при попытке? – NathanOliver