C++ 使用带有此指针参数的广义lambda的反射问题
我有3个编译器对以下C++14代码有不同意见:C++ 使用带有此指针参数的广义lambda的反射问题,c++,reflection,lambda,c++14,C++,Reflection,Lambda,C++14,我有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
#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)) {});
}
#包括
模板
constexpr自动can_调用(P*P,F&&F)->decltype(F(P),std::true_type{}{return{};}
模板
constexpr std::false_类型can_调用(void const*,F&&){return{};}
结构C{
C(){auto pc=can_调用(this,[&](auto p)->decltype(p->f(3)){}
无效f(int);
};
模板
结构CT{
CT(){auto ptc=can_调用(this,[&](auto p)->decltype(p->f(3)){}
空隙f(T);
};
int main()
{
C oc;
自动pc=can_调用(&oc,[&](自动p)->decltype(p->f(3)){});
CT-oct;
自动ptc=can_调用(&oct,[&](autop)->decltype(p->f(3)){});
}
clang++3.7毫无疑问地接受了它
g++4.9、5.1、5.2、5.3和trunk使CT
构造函数失败,并显示以下消息:
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)) {}); }
^
t.cpp:在“CT::CT()[with t=int]”的实例化中:
t、 cpp:24:11:此处为必填项
t、 cpp:16:61:错误:'->'的基操作数具有非指针类型“自动:2”
CT(){auto ptc=can_调用(this,[&](auto p)->decltype(p->f(3)){}
^
VisualStudio 2015社区与g++完全相反,除了模板化的CT
构造函数之外,它使所有lambda都失败,抱怨'->f'
的左边必须是指针。(我没有检查它是否在CT
构造函数中错误地获取了std::false_type
结果。)
由此,我有两个问题:
停止滥用那些糟糕的编译器。@rollbear删除显式返回类型(
->decltype(…)
东西)使其与所有三个编译器一起编译。@JameyD该建议有一些优点。@Drop yes,但如果无法调用函数,我想得到std::false_type
,而导致SFINAE选择的是显式返回类型。如果没有它,就会出现编译错误。MSVC仍然不擅长表达式SFINAE,GCC在模板中的lambdas存在许多问题。