2016-10-28 1 views
4

diesen Code vor:make_tuple mit Template-Parameter lässt sich nicht kompilieren

#include <tuple> 

int main() 
{ 
    int i; 
    long k; 

    auto tup1 = std::make_tuple<long>(i); // Compiles 
    auto tup2 = std::make_tuple<int>(k); // Compiles 
    auto tup3 = std::make_tuple<int>(i); // Does not compile 
    auto tup4 = std::make_tuple<int>(i+0); // Compiles 
    auto tup5 = std::make_tuple(i);   // Compiles 
} 

Warum auto tup3 = ... nicht kompilieren? Offensichtlich will make_tuple<int>(...) eine Rvalue-Referenz als sein Argument; aber warum?

(Ich bin mit GCC 6.1.0.)

+4

Sie sollen nicht Vorlagentyp Argumente in 'make_tuple' angeben, da sonst Sie Typen erzwingen, die nicht auf die Argumente binden kann –

+1

Als Wie oben erwähnt, sollten Sie keine Template-Typ-Argumente angeben. Wenn Sie einen rvalue erstellen möchten, verwenden Sie einfach std :: move. Dies würde kompilieren: auto tup3 = std :: make_tuple (Std :: move (i)); – Pani

Antwort

7

std::make_tuple und std::make_pair sind so konzipiert, Template-Parameter abzuleiten (unter anderem gleichem Bezug Wrapper Auspacken). Die explizite Angabe ist ein Fehler.

In diesem speziellen Fall ist es, weil Vorlage Abzug für rvalues ​​ihre Art ergibt, analog zu diesem Beispiel:

template<typename T> 
void foo(T&&); 

foo(42); // foo<int>(int&&) 
int i{}; 
foo(i); // foo<int&>(int&) // after reference collapsing 

und deshalb make_tuple<int>(...) einen rvalue Bezug auf ihr Argument will.

Wenn Sie Conversions zwingen wollen, alles, was Sie sagen müssen, ist

auto tup1 = std::tuple<long>(i); 
Verwandte Themen