模板类成员与非成员模板函数的歧义
Template class member vs. non-member template function ambiguity
我正在开发一个用于自动/算法区分的仅标头库。目标是能够简单地更改馈送到函数的变量的类型,并计算一阶和二阶导数。为此,我创建了一个模板类,允许程序员为私有数据成员选择存储类型。包括下面的一个代码片段,其中包含一个有问题的运算符重载。
template <typename storage_t>
class HyperDual
{
template <typename T> friend class HyperDual;
public:
template <typename T>
HyperDual<storage_t> operator+(const HyperDual<T>& rhs) const
{
HyperDual<storage_t> sum;
for (size_t i = 0; i < this->values.size(); i++)
sum.values[i] = this->values[i] + rhs.values[i];
return sum;
}
protected:
std::vector<storage_t> values;
};
稍后,为了最大限度地提高多功能性,我提供了模板函数以允许交互。
template <typename storage_t, typename T>
HyperDual<storage_t> operator+(const HyperDual<storage_t>& lhs, const T& rhs)
{
static_assert(std::is_arithmetic<T>::value && !(std::is_same<T, char>::value), "RHS must be numeric");
return HyperDual<storage_t>(lhs.values[0] + rhs);
}
template <typename storage_t, typename T>
HyperDual<storage_t> operator+(const T& lhs, const HyperDual<storage_t>& rhs)
{
static_assert(std::is_arithmetic<T>::value && !(std::is_same<T, char>::value), "LHS must be numeric");
return HyperDual<storage_t>(lhs + rhs.values[0]);
}
我遇到的是编译器正在尝试实例化第二个非成员模板函数。
#include "hyperspace.h"
int main()
{
HyperDual<long double> one(1); // There is an appropriate constructor
HyperDual<double> two(2);
one + two;
return 0;
}
为此,我收到static_assert生成的错误"LHS 必须是数字"。我将如何解决歧义?
使用enable_if_t
使非成员模板只能在特定上下文中应用?
template <typename storage_t, typename T, typename = enable_if_t<std::is_arithmetic<T>::value && !(std::is_same<T, char>::value)>>
HyperDual<storage_t> operator+(const HyperDual<storage_t>& lhs, const T& rhs)
{
static_assert(std::is_arithmetic<T>::value && !(std::is_same<T, char>::value), "RHS must be numeric");
return HyperDual<storage_t>(lhs.values[0] + rhs);
}
此处可能会重复static_assert
。
好的。我发现了自己的问题。这归结为static_assert和std::之间的区别enable_if
替换我的模板声明并删除static_assert,我实现了等效的功能:
template <typename storage_t, typename T,
typename = typename std::enable_if<std::is_arithmetic<T>::value && !std::is_same<T, char>::value>::type>
HyperDual<storage_t> operator+(const T& lhs, const HyperDual<storage_t>& rhs)
{
return HyperDual<storage_t>(lhs + rhs.value());
}
(小细节,但rhs.values[0]
被替换为rhs.value()
。这与模板问题无关,但与成员访问有关。
相关文章:
- 将成员变量添加到共享库中的类中,不会破坏二进制兼容性吗
- 对RValue对象调用的LValue ref限定成员函数
- 为什么使用 "this" 指针调用派生成员函数?
- 具有奇怪重复模板模式的派生类中的成员变量已损坏
- 助记符和指向成员语法的指针
- 用于访问容器<T>数据成员的正确 API
- 内置函数可查看CPP中的成员变量
- 是否可以初始化不可复制类型的成员变量(或基类)
- 如果C++类在类方法中具有动态分配,但没有构造函数/析构函数或任何非静态成员,那么它仍然是POD类型吗
- 找不到成员对象:没有名为get_event()的成员,也处理多态性和向量
- 消除好友和成员二进制运算符的歧义
- C++SFINAE enable_if_t成员函数,如何消除歧义?
- C++中成员名称查找和访问声明中的歧义
- 在C 中,静态成员函数是否继承了?如果是,为什么没有出现歧义错误
- 模板类成员与非成员模板函数的歧义
- 消除多重继承中类成员的歧义
- 消除作为模板参数传递的重载成员函数指针的歧义
- 数据成员访问歧义和菱形继承
- 为什么我不能使用 using 来消除基本成员变量之间的歧义?
- 模板的模板成员的消除歧义器模板关键字:确切时间