定义模板化操作符重载时出错
Error defining a templated operator overload
这是一个操作符+的模板化重载尝试。在gcc 4.8和icc 14.0.3下都无法编译。
template <typename T>
class B
{
public:
B operator+(const B& rhs)
{
return *this;
}
};
template <typename T>
class A
{
public:
operator B<T>() const{return B<T>();}
};
// template<typename T>
// B<T> operator+(A<T> const& t, A<T> const& u)
// {
// return (B<T>)t + (B<T>)u;
// }
template<typename T, typename U>
B<U> operator+(A<T> const& t, A<T> const& u)
{
return (B<U>)t + (B<U>)u;
}
int main()
{
A<double> a,b;
B<double> c = a+b;
return 0;
}
但是,注释的重载工作得很好。有什么区别呢?为什么有两个参数的模板不匹配?
g++48 -std=c++11 temp2.cpp
temp2.cpp: In function ‘int main()’:
temp2.cpp:33:18: error: no match for ‘operator+’ (operand types are ‘A<double>’ and ‘A<double>’)
B<double> c = a+b;
^
temp2.cpp:33:18: note: candidate is:
temp2.cpp:25:6: note: template<class T, class U> B<U> operator+(const A<T>&, const A<T>&)
B<U> operator+(A<T> const& t, A<T> const& u)
^
temp2.cpp:25:6: note: template argument deduction/substitution failed:
temp2.cpp:33:19: note: couldn't deduce template parameter ‘U’
B<double> c = a+b;
编译器告诉你失败的原因:
temp2.cpp:25:6:注意:模板参数演绎/替换失败:
temp2.cpp:33:19:注意:无法推断模板参数' U '
模板参数U
只出现在函数模板的返回类型中,因此无法推导。如果显式列出模板参数
B<double> c = operator+<double, double>(a, b);
如果你交换模板参数的顺序,使U
出现在T
之前,你仍然可以允许T
被推导出来。
template<typename U, typename T>
B<U> operator+(A<T> const& t, A<T> const& u)
{
return (B<U>)t + (B<U>)u;
}
B<double> c = operator+<double>(a, b);
注释掉的operator+
实现有效,因为返回类型也使用相同的类型参数T
,因此允许它从函数模板参数中推导出来。
In
B<double> c = a+b;
中的类型模板参数U
B<U> operator+(A<T> const& t, A<T> const& u)
不能推导。U
不会被推断为double
,因为调用的结果被赋值给B<double>
。您必须显式地将U
指定为double
,例如:
B<double> c = operator+<double, double>(a, b);
显然,这可能不是一个理想的情况。那么你能做些什么呢?嗯,很难说,因为您没有指定A
和B
要用于什么。但是,正如您已经发现的那样,您的代码使用注释掉的操作符
template<typename T>
B<T> operator+(A<T> const& t, A<T> const& u)
{
return (B<T>)t + (B<T>)u;
}
出于某种原因,您似乎希望可以使用结果来初始化B<U>
,其中U
可能与T
不同,因此也许正确的解决方案是使B<T>
可以构造B<U>
:
template <typename T>
class B
{
public:
template <typename U>
B(const B<U>& rhs) {
// ...
}
// ...
};
(您可能还想编写类似的赋值操作符)
来自编译器的错误信息是清楚的。无法推导参数U
来实例化operator+
函数。
可以使用:
B<double> c = operator+<double, double>(a,b);
没有推导返回类型。
你可以用表达式模板来代替。
template<template<class>class Op, class Rhs, class Lhs>
struct deferred{
Lhs lhs; Rhs rhs;
template<typename Result>
operator Result() const { return Op<Result>{}( std::forward<Lhs>(lhs), std::forward<Rhs>(rhs) ); }
};
template<class R> sum;
template<class U> sum<B<U>>{
template<class Lhs, class Rhs>
B<U> operator()( A<Lhs> const& lhs, A<Rhs> const& rhs )const{
return B<Lhs>(lhs)+B<Rhs>(rhs);
}
};
template<class T>
deferred<sum, A<T>const&, A<T>const&> operator+( A<T>const& a, A<T>const& b){
return {a,b};
}
相关文章:
- 重载操作程序时出错>>用于类中的字符串 memebr
- 在 myVector 类中重载运算符 + 时出错
- 在重载 + 和 - 运算符时出错
- 重载运算符时出错<在 sf::Vector 中
- Rcpp/C++/R:比较日期时间矢量与日期时间时出错(错误:"运算符>"的不明确重载)
- 尝试重载模板类友元<<运算符时出错
- 尝试使用浮点参数运行重载函数时出错
- 使用 getline 重载 istream 运算符>> 会出错
- 构建 castalia 时出错:重载函数的调用不明确
- 模板化函数重载和类外定义时出错
- 运算符重载时出错(错误:"运算符<<不匹配(操作数类型为"std::basic_ostream<char>"和"const char [2]")
- 重载前模板实例化出错
- 创建重载运算符时出错
- 重载运算符 + C++ 时出错
- C++中的重载<<出错
- 重载运算符时出错(必须是非静态成员函数)
- LNK 2019 尝试重载"<<"操作器时出错
- 实现重载运算符'<<'时出错 - C++
- C++在重载运算符时出错,未满负荷
- 模板运算符重载时出错