考虑以下典型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 ++。请显示一个完整的示例程序来演示错误,我显然不会像您一样测试相同的东西。 –