2017-02-02 33 views
10

我想以通用的方式獲取返回類型std::begin。我目前的解決方案是:獲取c數組上的開始返回類型

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

它工作時T = std::vector<int>。但我不明白爲什麼下面不工作:

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

我得到的錯誤:

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

如何獲得的std::begin返回類型在一個通用的方式?

回答

7

的過載arrays是:

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

而且std::declval<int[3]>()給你一個int(&&)[3],不說超載匹配。它也不符合正常的集裝箱過載,因爲那些是SFINAE編輯的c.begin()。所以你沒有匹配的功能。

你需要的是將一個左值對數組的引用傳遞給begin(),以使迭代器返回。因此,無論您需要手動提供的是左值引用當您使用別名:

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

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

或者有別名本身爲您提供左值參考:

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

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

前者似乎更正確的我,但是YMMV。