Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/125.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 使用带有此指针参数的广义lambda的反射问题_C++_Reflection_Lambda_C++14 - Fatal编程技术网

C++ 使用带有此指针参数的广义lambda的反射问题

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

我有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)) {});
}
#包括
模板
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
结果。)

由此,我有两个问题:

  • 人们期望什么?我曾试图阅读github的(草案C++17)标准,但说实话,我甚至不知道该去哪里看,尤其是因为编译器有点太不同意
  • 可以用不同的方式移植预期的反射吗?我想要(不需要)改进库中编译错误消息的功能

  • 停止滥用那些糟糕的编译器。@rollbear删除显式返回类型(
    ->decltype(…)
    东西)使其与所有三个编译器一起编译。@JameyD该建议有一些优点。@Drop yes,但如果无法调用函数,我想得到
    std::false_type
    ,而导致SFINAE选择的是显式返回类型。如果没有它,就会出现编译错误。MSVC仍然不擅长表达式SFINAE,GCC在模板中的lambdas存在许多问题。