C++ 使用成员函数时,使用std::result_编译失败

C++ 使用成员函数时,使用std::result_编译失败,c++,c++11,C++,C++11,在我附加的代码中,我正在寻找一种将一种类型映射到另一种类型的方法。代码编译失败,出现错误 [root@]# g++ -std=c++11 test.cpp -o test; ./test test.cpp: In member function ‘void A::Func(AType)’: test.cpp:32:58: error: template argument 1 is invalid using BType = std::result_of<GetBTypeFromA

在我附加的代码中,我正在寻找一种将一种类型映射到另一种类型的方法。代码编译失败,出现错误

[root@]# g++ -std=c++11 test.cpp -o test; ./test
test.cpp: In member function ‘void A::Func(AType)’:
test.cpp:32:58: error: template argument 1 is invalid
     using BType = std::result_of<GetBTypeFromAType(AType)>::type;
[root@]#g++-std=c++11 test.cpp-o test/测试
test.cpp:在成员函数“void A::Func(AType)”中:
test.cpp:32:58:错误:模板参数1无效
使用BType=std::result\u of::type;
我使用的编译器版本是5.3.1,你知道如何修复吗

#include <iostream>
#include <typeinfo>
#include <cxxabi.h>
#include <memory>

template <class T>
std::string GetTypeName()
{
  //http://stackoverflow.com/questions/23266391/find-out-the-type-of-auto/23266701#23266701
  std::unique_ptr<char, void(*)(void*)> name{abi::__cxa_demangle(typeid(T).name(), 0, 0, nullptr), std::free};
  return name.get();
}


struct A
{
  struct AA {};
  struct AB {};
  struct AC {};

  struct BA {};
  struct BB {};
  struct BC {};

  BA GetBTypeFromAType(AA a) { return BA(); }
  BB GetBTypeFromAType(AB a) { return BB(); }
  BC GetBTypeFromAType(AC a) { return BC(); }

  template <typename AType>
  void Func(AType a)
  {
    using BType = std::result_of<GetBTypeFromAType(AType)>::type;
    std::cout << "Func called with " << GetTypeName<AType>() << " and got " << GetTypeName<BType>() << std::endl;
  }
};

int main()
{
  A a;
  A::AA aa;
  A::AB ab;
  A::AC ac;
  a.Func(aa);
  a.Func(ab);
  a.Func(ac);
  return 0;
}
#包括
#包括
#包括
#包括
模板
std::string GetTypeName()
{
//http://stackoverflow.com/questions/23266391/find-out-the-type-of-auto/23266701#23266701
std::unique_ptr name{abi::ucxa_demangle(typeid(T).name(),0,0,nullptr),std::free};
返回name.get();
}
结构A
{
结构AA{};
结构AB{};
结构AC{};
结构BA{};
结构BB{};
结构BC{};
BA GetBTypeFromAType(AA a){return BA();}
BB GetBTypeFromAType(AB a){return BB();}
BC GetBTypeFromAType(AC a){return BC();}
模板
无效函数(a型)
{
使用BType=std::result\u of::type;

std::cout我认为您应该为
std::result\u提供结果类型,而不是函数名

也许你可以试着用这个来代替:

using BType = decltype(GetBTypeFromAType(a));

template <typename AType>
void Func(AType a) {
  using BType = decltype(GetBTypeFromAType(AType{}));
  std::cout << "Func called with " << GetTypeName<AType>() << " and got " << GetTypeName<BType>() << std::endl;
}

为什么不创建一个简单的trait类(前提是您实际上不需要原始方法,而只需要将一种类型映射到另一种类型):

模板
结构GetBTypeFromAType;
结构A
{
结构AA{};
结构AB{};
结构AC{};
结构BA{};
结构BB{};
结构BC{};
模板
无效函数(a型)
{
使用BType=typename GetBTypeFromAType::type;
// ...
}
};
模板结构GetBTypeFromAType{using type=A::BA;};
模板结构GetBTypeFromAType{using type=A::BB;};
模板结构GetBTypeFromAType{using type=A::BC;};
棘手的是
F(Args…
语法有误导性。因为它看起来像一个函数,所以你很想把它当作函数来调用。(我认为这种古怪的语法是它在C++17中被弃用的部分原因)

但是,
F
必须是类型而不是函数名,因此说
GetBTypeFromAType
是不够的(您需要它的类型)

但是,由于它是重载的,您不能简单地将其包装在一个
decltype
中;您需要转换到适当的重载以获得正确的指针,这会破坏整个目的(因为如果您知道它将调用哪个重载,您首先就不需要询问返回类型)

std::result\u of
最好与函数对象一起使用,因此最简单的解决方法是在lambda中包装对
GetBTypeFromAType
的调用,然后在该lambda上使用
decltype

template <typename AType>
void Func(AType a)
{
  auto wrapper = [this](AType&& a){return GetBTypeFromAType(std::forward<decltype(a)>(a));};
  using BType = typename std::result_of<decltype(wrapper)(AType)>::type;
  std::cout << "Func called with " << GetTypeName<AType>() << " and got " << GetTypeName<BType>() << std::endl;
}
模板
无效函数(a型)
{
自动包装器=[this](AType&&a){return GetBTypeFromAType(std::forward(a));};
使用BType=typename std::result\u of::type;

std::cout(不相关,但不要以root用户的身份进行开发工作。只有在必要时才提升priv。)我将使用您的代码,这比的result_容易得多,但问题是关于的result_,所以我接受了@AndyG Answer。出于某种原因,我的代码中的模板专门化存在一些问题,使用重载函数对我来说非常好。不过,您的解决方案可能是将一种类型映射到另一种类型的最佳方案
template<typename T>
struct GetBTypeFromAType;

struct A
{
  struct AA {};
  struct AB {};
  struct AC {};

  struct BA {};
  struct BB {};
  struct BC {};

  template <typename AType>
  void Func(AType a)
  {
    using BType = typename GetBTypeFromAType<AType>::type;
    // ...
  }
};

template<> struct GetBTypeFromAType<A::AA> { using type = A::BA; };
template<> struct GetBTypeFromAType<A::AB> { using type = A::BB; };
template<> struct GetBTypeFromAType<A::AC> { using type = A::BC; };
template <typename AType>
void Func(AType a)
{
  auto wrapper = [this](AType&& a){return GetBTypeFromAType(std::forward<decltype(a)>(a));};
  using BType = typename std::result_of<decltype(wrapper)(AType)>::type;
  std::cout << "Func called with " << GetTypeName<AType>() << " and got " << GetTypeName<BType>() << std::endl;
}