2014-09-14 3 views
5

У меня есть следующий шаблон функции:шаблон Функция удержания и initlializer_list

template <typename K, typename V> 
void f(std::initializer_list<std::pair<const K, V>> il) 
{ 
    //... 
} 

я называю функцию следующим образом:

f({std::pair<const int,int>(1,2), std::pair<const int,int>(3,4)}); //(a) 

и она отлично работает.

Однако, если я пытаюсь и назвать его следующим образом:

f({{1,2}, {3,4}}); //(b) 

не в состоянии вывести правильный тип, и я получаю ошибку компиляции вдоль линий:

'no matching function for call to 'f(<brace-enclose initializer list>) 
note candidate is: 
note: template <class K, class V> void f(std::initializer_list<std::pair<const K, V>>)' 

Если я назову его следующим:

f({std::pair<const int,int>(1,2), {3,4}}); //(c) 

Тип дедукции работает, но если я попробую назвать его следующим образом:

f({std::make_pair(1,2), {3,4}}); //(d) 

Я получаю ту же ошибку компиляции, что и ранее.

Мой вопрос:

Почему тип шаблона вычет работа (с), но не в (г)?

(Компилятор GCC v4.6.3, с флагом -std = C++ 11)

Я смотрел на аналогичный, старших SO постов, но они, кажется, не совсем ответить на этот вопрос.

ответ

4

Проблема с б) является то, что компилятор не может вывести типы, так как что-то вроде

{1,2} 

могли бы также быть приняты для initializer_list<int>, проблема с г) является что make_pair не будет генерировать const int для первой части пары

+0

Да, я подумал с помощью b), что, однако, не могло забыть о не const int из make_pair. Благодарю. – TPJ

+0

'{1,2}' is not "взято для' initializer_list '', это не выводимый контекст, если он не сопряжен с 'initializer_list '. Есть разница (если компилятор фактически вывел 'initializer_list ' из '{1, 2}' во всех случаях, то (с) не будет компилироваться). –

+0

Я переформулировал предложение, спасибо! –