2013-08-13 7 views
12

sagen, es gibt zwei Funktionen:Wie erstellt man ein Tupel von Const-Referenzen?

void ff(const std::tuple<const int&>) { } 

template < typename TT > 
void gg(const std::tuple<const TT&>) { } 

und ruft auf diese Funktionen:

int xx = 0; 
ff(std::tie(xx)); // passes 
gg(std::tie(xx)); // FAILS !! 

GCC 4.7.2 nicht die letzte Zeile zu kompilieren und meldet einen Fehlerhinweis wie:

note: template argument deduction/substitution failed: 
note: types ‘const TT’ and ‘int’ have incompatible cv-qualifiers 
note: ‘std::tuple<int&>’ is not derived from ‘std::tuple<const TT&>’ 

Die erste Frage ist, ob dies mit dem C++ 11-Standard übereinstimmt, und wenn nicht, warum?

Um dieses Problem zu beheben, muss man außerdem ein Tupel von const-Referenzen an gg übergeben, anstatt ein Tupel von nicht-konformen Referenzen zu übergeben (was std::tie macht). Dies kann geschehen durch:

gg(std::tie(std::cref(x))); 

jedoch ein zusätzlicher Anruf std::cref Art von langweilig ist, so es wäre toll, so etwas wie ctie zu haben, die ein Tupel von const Referenzen machen würden.

Die zweite Frage ist, ob es notwendig ist, ctie manuell zu schreiben, und wenn ja, dann ist dies der beste Weg, es zu tun?

template < typename... T > 
std::tuple<const T&...> ctie(const T&... args) 
{ 
    return std::tie(args...); 
} 
+3

[Relevant, aber nicht ein Betrogener.] (Http://StackOverflow.com/a/7867662/500104) – Xeo

+2

'zurück std :: move ();' ist ein Anti-Muster - es ist universell besser, einfach 'return ;' In diesem speziellen Fall ist 'std :: tie (args ...)' sowieso schon ein rvalue. [Siehe diese Antwort zur Diskussion] (http://stackoverflow.com/a/15981233/923854). – Casey

Antwort

2

Die erste Frage ist, ob dies mit dem passt C++ 11-Standard, und wenn dies nicht der Fall, dann warum?

Dies ist das erwartete Verhalten. Im zweiten Fall schlägt der Abzug der Vorlagenargumente fehl, weil T nicht vorhanden ist, so dass tuple<const T&>tuple<int&> wird. Im ersten Fall funktioniert es, weil tuple<int&> implizit in konvertiert werden kann. Dies ist eine benutzerdefinierte Konvertierung und wird daher beim Ableiten von Vorlagenargumenten nicht berücksichtigt.

Ihre Fragen riechen ein bisschen wie ein X/Y-Problem. Ziehen Sie in Erwägung, die echte Frage zu stellen, die Sie nach einer Lösung mit dieser Art von Funktionsvorlage/Tupel-Kombination suchen ließ.

Ihre ctie Funktionsvorlage sieht gut aus. Aber bedenken Sie, dass Dinge wie

auto t = ctie(5); 

im Grunde wird eine baumelnde Referenz produzieren. So können Sie ctie auf nur lvalues ​​einschränken.