GCC失败了可变参数模板和指向成员函数的指针

时间:2015-12-26 00:57:19

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

#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 > 

1 个答案:

答案 0 :(得分: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);

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