【问题标题】:GCC failed with variadic template and pointer to member functionGCC 因可变参数模板和指向成员函数的指针而失败
【发布时间】:2015-12-26 00:57:18
【问题描述】:
#include <memory>
#include <iostream>

class           Manager
{
public:
  Manager() {}
  virtual ~Manager() {}

  int funcA(std::shared_ptr<int> a, float b) { return *a + b; }
  int funcA(std::shared_ptr<double> a) { return *a; }
};

template <typename T, typename... Args>
auto resolver(int (Manager::*func)(std::shared_ptr<T>, Args...)) -> decltype(func) {
  return func;
}                                                                                                                                  

int main(int, char **)
{
  Manager m;
  Manager *ptr = &m;

  auto var = std::make_shared<int>(1);

  int result = (ptr->*resolver<int>(&Manager::funcA))(var, 2.0);

  std::cout << result << std::endl;

  return 0;
}

此代码无法使用 gcc 编译,但可以使用 clang。 (gcc 5.3.1 和 6.0.0 20151220)。

您知道是否有任何解决方案可以使其与 gcc 一起编译?我尝试了模板专业化和显式实例化。

编辑:gcc 给出以下错误:

test > g++ -std=c++11 test.cpp 
test.cpp: In function 'int main(int, char**)':
test.cpp:29:52: error: no matching function for call to 'resolver(<unresolved overloaded function type>)'
   int result = (ptr->*resolver<int>(&Manager::funcA))(var, 2.0);
                                                    ^
test.cpp:15:6: note: candidate: template<class T, class ... Args> decltype (func) resolver(int (Manager::*)(std::shared_ptr<_Tp1>, Args ...))
 auto resolver(int (Manager::*func)(std::shared_ptr<T>, Args...)) -> decltype(func) {
      ^
test.cpp:15:6: note:   template argument deduction/substitution failed:
test.cpp:29:52: note:   mismatched types 'std::shared_ptr<int>' and 'std::shared_ptr<double>'
   int result = (ptr->*resolver<int>(&Manager::funcA))(var, 2.0);
                                                    ^
test.cpp:29:52: note:   could not resolve address from overloaded function '& Manager::funcA'
test > 

【问题讨论】:

  • 它给出的错误是什么?
  • @0x499602D2 我刚刚编辑了我的帖子
  • 这里的主要问题是resolver&lt;int&gt;(&amp;Manager::funcA)(注意:这个表达式需要自己解析,下面的参数列表(var,2.0)不是&amp;Manager::funcA重载解析的一部分)。似乎clang决定funcA的单参数版本不是候选人,但gcc决定两者都是候选人。如果有多个候选人,那么&amp;Manager::funcA 将是格式错误的 ([expr.unary.op]/6)。请注意,如果您有任何其他 funcA 重载,这显然是模棱两可的,所以我认为您尝试实施的任何想法都行不通
  • IOW 的问题是是否允许将 Args 推断为空列表(并且在这种情况下,将 (std::shared_ptr&lt;T&gt;, Args...) 视为 (std::shared_ptr&lt;T&gt;)
  • @M.M 编写解析器部分)应该足以推断出函数类型,不是吗?

标签: c++ c++11 gcc c++14


【解决方案1】:

作为一种解决方法,您可以使用

template <typename T>
struct resolver
{
    template <typename... Args>
    auto operator ()(int (Manager::*func)(std::shared_ptr<T>, Args...)) -> decltype(func) {
      return func;
    }
};

像调用一样

(ptr->*resolver<int>{}(&Manager::funcA))(var, 2.0);

注意额外的{} 来调用构造函数。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-10-20
    • 1970-01-01
    • 2013-04-30
    • 2020-12-08
    • 2017-02-24
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多