我有3个编译器不同意下面的C ++ 14代码:
#include <type_traits>
template <typename P, typename F>
constexpr auto can_call(P* p, F&& f) -> decltype(f(p),std::true_type{}) { return {}; }
template <typename F>
constexpr std::false_type can_call(void const*, F&&) { return {}; }
struct C {
C() { auto pc = can_call(this, [&](auto p) -> decltype(p->f(3)) {}); }
void f(int);
};
template <typename T>
struct CT {
CT() { auto ptc = can_call(this, [&](auto p) -> decltype(p->f(3)) {}); }
void f(T);
};
int main()
{
C oc;
auto pc = can_call(&oc, [&](auto p) -> decltype(p->f(3)) {});
CT<int> oct;
auto ptc = can_call(&oct, [&](auto p) -> decltype(p->f(3)) {});
}
clang ++ 3.7毫不犹豫地接受了它。
g ++ 4.9,5.1,5.2,5.3和trunk使CT<T>
构造函数失败,并显示以下消息:
t.cpp: In instantiation of ‘CT<T>::CT() [with T = int]’:
t.cpp:24:11: required from here
t.cpp:16:61: error: base operand of ‘->’ has non-pointer type ‘auto:2’
CT() { auto ptc = can_call(this, [&](auto p) -> decltype(p->f(3)) {}); }
^
VisualStudio 2015社区与g ++完全相反,并且除了模板CT<T>
构造函数之外,所有lambdas都失败了,抱怨'->f'
的左边必须是指针。 (我没有检查是否错误地在std::false_type
构造函数中获得CT<T>
结果。)
由此我有两个问题: