2014-01-19 2 views
1

Возможно, я глуп, но я не понимаю, в чем проблема с этим кодом. Я начинаю прибегать к сомнению своих инструментов. Я использую Clang (C++ 11) и его libC++. Если это моя вина, я извиняюсь, и спасибо заранее, кто указывает мою тупость, но если это не так, может быть, это более глубокий вопрос ..Объявление типов шаблонов для вызова make_pair

std::map<int, bool> map_; 

map_.insert(std::make_pair<int, bool>(5, true)); //Use a literal, compiles OK 

int x = 5; 
map_.insert(std::make_pair<int, bool>(x, true)); //Use a local of same type, compile error: 'no known conversion from 'int' to 'int &&' for 1st argument' 
+4

Вы не должны предоставлять аргументы шаблона, но пусть дедукции делать свою работу: 'станд :: make_pair (х, правда) ' – juanchopanza

+0

' std :: make_pair' обычно принимает это и дает ему тип 'int & &&' или 'int &'. Теперь вы ушли и сделали это 'int &&', который нельзя использовать с lvalue. – chris

+0

Да, это исправляет. Но мне интересно, почему .. принудительное использование версии шаблона функции, которая соответствует аргументам, должна давать ту же реализацию, конечно? – NitrousUK

ответ

8

std::make_pair принимает "universal reference" к его аргументам. Универсальная ссылка может связываться почти со всем. Это фактическая подпись:

template< class T1, class T2 > 
constexpr std::pair<V1,V2> make_pair(T1&& t, T2&& u); 
//         ^^^^^^^^^^^^^^ 

Когда вы явно задать тип (т.к я мог бы добавить), он превращает вызов функции в этом:

... (int&& t, bool&& u); 

имеет следующее значение аргументы больше не являются универсальными ссылками, а rvalue-ссылками. Rvalue-ссылки могут связываться только с rvalues, а не с lvalues, поэтому ошибка для первого аргумента.

Решение этой проблемы является предоставление аргументов шаблона вычет делать свою работу:

map_.insert(std::make_pair(x, true)); 
Смежные вопросы