Hir*_*aCC 9 c++ templates ambiguous ambiguous-call template-argument-deduction
我正在做一些看起来像这样的包装器:
#include <iostream>
template<class T, class Value>
void Apply(void (T::*cb)(Value), T* obj, Value v)
{
(obj->*cb)(v);
}
class Foo
{
public:
void MyFunc(const int& i)
{
std::cout << i << std::endl;
}
const int& GetValue()
{
return i_;
}
private:
int i_ = 14;
};
int main()
{
Foo f;
Apply(&Foo::MyFunc, &f, f.GetValue());
}
Run Code Online (Sandbox Code Playgroud)
我收到这个错误:
Apply:找不到匹配的重载函数. void Apply(void (__thiscall T::* )(Value),T *,Value):模板参数Value不明确,可能是int或const int &. void Apply(void (__thiscall T::* )(Value),T *,Value):无法推断Valuefrom的模板参数const int. 所以我得到它来自模板参数推导,但我不明白如何.为什么Value 不评估const int&两次?
Bar*_*rry 13
目前,模板参数Value在调用中的两个不同位置推导出Apply:从指针到成员函数参数和从最后一个参数.从&Foo::MyFunc,Value推断为int const&.从f.GetValue(),Value推断为int.这是因为为了模板推断而删除了引用和顶级cv限定符.由于参数的这两个推论Value不同,因此推论失败 - Apply()从过载集中删除,因此我们没有可行的过载.
问题是Value在两个不同的地方推断出来,所以让我们来防止这种情况发生.一种方法是在非推导的上下文中包含其中一个用法:
template <class T> struct non_deduced { using type = T; };
template <class T> using non_deduced_t = typename non_deduced<T>::type;
template<class T, class Value>
void Apply(void (T::*cb)(Value), T* obj, non_deduced_t<Value> v)
{
(obj->*cb)(v);
}
Run Code Online (Sandbox Code Playgroud)
最后一个参数v是类型non_deduced_t<Value>,顾名思义,它是一个非推导的上下文.因此,在模板推导过程中,从指向成员函数的指针(如前所述)Value推导出来int const&,现在我们只需将其插入到类型中即可v.
或者,您可以选择推导cb为自己的模板参数.在这一点上Apply()只减少到std::invoke().
| 归档时间: |
|
| 查看次数: |
839 次 |
| 最近记录: |