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