考慮以下典型SFINAE測試功能(它檢查是否一個類型具有begin()
成員函數)SFINAE:如果調用無參數曖昧過載
template <class> constexpr bool
has_begin_member (...) { return false; }
template <class T> constexpr bool
has_begin_member (decltype (std::declval <T>().begin())* = 0) {
return true;
}
我可以與一個參數調用它:
has_begin_member <int> (0); // yields false
,但不帶任何參數:
has_begin_member <int>(); // compilation error
它會導致以下不確定性:
爲什麼在這種情況下「省略技巧」不起作用?
編輯:完整的程序:
#include <utility>
#include <vector>
template <class> constexpr bool
has_begin_member (...) { return false; }
template <class T> constexpr bool
has_begin_member (decltype (std::declval <T>().begin())* = 0) {
return true;
}
static_assert (!has_begin_member <int> (0), "broken");
static_assert (has_begin_member <std::vector <int>> (0), "broken");
static_assert (!has_begin_member <int>(), "broken");
static_assert (has_begin_member <std::vector <int>>(), "broken");
int
main(){}
編譯:
g++ -std=c++11 -o toto ./toto.cpp
./toto.cpp:17:58: error: call of overloaded 'has_begin_member()' is ambiguous
./toto.cpp:17:58: note: candidates are:
./toto.cpp:5:5: note: constexpr bool has_begin_member(...) [with <template-parameter-1-1> = std::vector<int>]
./toto.cpp:8:5: note: constexpr bool has_begin_member(decltype (declval<T>().begin())*) [with T = std::vector<int>; decltype (declval<T>().begin()) = __gnu_cxx::__normal_iterator<int*, std::vector<int> >]
你使用什麼編譯器? –
g ++(GCC)4.7.1 20120721(預發佈) – manu
我認爲這看起來像GCC診斷,但它對我來說也適用於G ++ 4.5,4.6,4.7,4.8和Clang ++。請顯示一個完整的示例程序來演示錯誤,我顯然不會像您一樣測試相同的東西。 –