2017-02-02 3 views
10

Ich möchte den Rückgabetyp von std::begin in einer allgemeinen Art und Weise erhalten. Meine aktuelle Lösung ist:Erhalten Sie den Rückgabetyp von Anfang auf einem c-Array

using type = decltype(std::begin(std::declval<T>())); 

und es funktioniert, wenn T = std::vector<int>. Aber ich verstehe nicht, warum die folgenden nicht funktioniert:

using type = decltype(std::begin(std::declval<int[3]>())); 

ich den Fehler:

example.cpp:83:60: error: no matching function for call to ‘begin(int [3])’ 
    using type = decltype(std::begin(std::declval<int[3]>())); 

Wie den Rückgabetyp std::begin in allgemeiner Weise zu bekommen?

Antwort

7

Die Überlastung für arrays ist:

template< class T, std::size_t N > 
constexpr T* begin(T (&array)[N]); 

Und std::declval<int[3]>() gibt Ihnen eine int(&&)[3], die nicht, dass Überlast entspricht. Es entspricht auch nicht der normalen Container-Überlastung, da diese SFINAE-ed auf c.begin() haben. Sie haben also keine übereinstimmende Funktion.

Sie müssen stattdessen einen lvalue Verweis auf Array an begin() übergeben, um den Iterator wieder heraus zu bekommen. So müssen Sie entweder manuell ein schaffen, die Referenz Lvalue, wenn Sie Ihren Alias:

template <class T> 
using type = decltype(std::begin(std::declval<T>())); 

using arr = type<int(&)[3]>; // int* 

oder haben den Alias ​​selbst für Sie die lvalue Referenz zur Verfügung stellen:

template <class T> 
using type = decltype(std::begin(std::declval<T&>())); 

using arr = type<int[3]>; // int* 

Erstere scheint mir richtig , aber YMMV.

Verwandte Themen