我试图重载一个乘法运算符,但不想输入多个重载函数来考虑整数与浮点、整数与双精度、浮点与整数的乘法等等。。。我希望编写一个重载运算符来解释所有带浮点数、整数和double的乘法组合,并得到正确的返回类型。我得到的错误是,没有找到接受“Widget::Widget”类型的右操作数的运算符(或者没有可接受的转换)。我想这是因为我正在使用decltype来设置返回对象小部件的模板类型。如果返回不是模板对象,则使用尾部返回类型有效。
下面是一个重载运算符的示例:
template<typename T1, typename T2>
auto
operator*(const Widget<T1>& aWidge, const Widget<T2>& bWidge) -> Widget<decltype(aWidge.x*bWidge.x)>
{
Widget<decltype(aWidge.x*bWidge.x)> result;
//do stuff needed when multiplying two Widgets
return result;
}
template<typename T>
Widget<T>& Widget<T>::operator=(const Widget<T>& aWidget)
{
x = aWidget.x;
return *this;
}
下面是模板类的一个例子
template<typename T> class Widget
{
private:
T x;
public:
Widget();
~Widget();
void SetX(T value);
Widget<T>& operator=(const Widget<T>& aWidget);
}
示例Main.cpp
int main()
{
Widget<int> aWidge;
Widget<float> bWidge;
Widget<float> cWidge;
aWidge.SetX(2);
bWidge.SetX(2.0);
cWidge = aWidge*bWidge; //this should give a float return type
}
视觉工作室2012
不要介意那些草率的代码。这是一个快速修复的代码,没有正确编译开始(不管自动decltype问题)。
template<typename T>
class Widget
{
public:
T x;
public:
Widget()
: x(666)
{}
~Widget() {}
void SetX(T value)
{
x = value;
}
Widget<T>& operator=(const Widget<T>& aWidget)
{
x = aWidget.x;
return *this;
}
};
template<typename T1, typename T2>
auto operator*(const Widget<T1>& aWidge, const Widget<T2>& bWidge) -> Widget<typename std::remove_const<decltype(aWidge.x*bWidge.x)>::type>
{
Widget<typename std::remove_const<decltype(aWidge.x*bWidge.x)>::type> result;
result.x = aWidge.x * bWidge.x;
return result;
}
int main ()
{
Widget<int> aWidge;
Widget<float> bWidge;
Widget<float> cWidge;
aWidge.SetX(2);
bWidge.SetX(2.0);
cWidge = aWidge*bWidge; //this should give a float return type
}
仔细阅读错误消息,问题很明显:
candidate template ignored: substitution failure [with T1 = int, T2 = float]: 'x' is
a private member of 'Widget<int>'
非成员二进制运算符*
试图在其声明(和定义)中访问私有成员x
。由于您有一个setter函数,一个简单的解决方案是还定义一个getter,并且只通过该函数访问成员x
:
template<typename T> class Widget
{
private:
T x;
public:
Widget() {}
~Widget() {}
void SetX(T value) {}
T& GetX() { return x; }
const T& GetX() const { return x; }
Widget<T>& operator=(const Widget<T>& aWidget);
};
template<typename T1, typename T2>
auto
operator*(const Widget<T1>& aWidge, const Widget<T2>& bWidge)
-> Widget<decltype(aWidge.GetX()*bWidge.GetX())>
{
Widget<decltype(aWidge.GetX()*bWidge.GetX())> result;
//...
return result;
}
另一个选择是让操作员*
成为朋友:
template<typename T> class Widget
{
private:
T x;
template<typename T1, typename T2>
friend auto
operator*(const Widget<T1>& aWidge, const Widget<T2>& bWidge)
-> Widget<decltype(aWidge.x*bWidge.x)>;
public:
Widget() {}
~Widget() {}
void SetX(T value) {}
Widget<T>& operator=(const Widget<T>& aWidget);
};
template<typename T1, typename T2>
auto
operator*(const Widget<T1>& aWidge, const Widget<T2>& bWidge)
-> Widget<decltype(aWidge.x*bWidge.x)>
{
Widget<decltype(aWidge.x*bWidge.x)> result;
return result;
}
或者,让它成为一个成员函数(感谢WhozCraig)。
你可能还需要
typename std::decay<decltype(aWidge.x*bWidge.x)>::type
而不仅仅是decltype(aWidge.x*bWidge.x)
。
其他选择包括
typename std::decay<decltype(std::declval<T1>()*std::declval<T2>())>::type
完全绕过了前面的问题(感谢亚当),或者
typename std::common_type<T1, T2>::type
它应该适合这个目的,可以说是最简单的形式。
我正在学习C 17非类型模板参数的新功能。我编写了一个简单的代码片段,如下所示: 据我所知,福 但是,语句使用clang、MSVC 19.27编译,但在GCC 10.2、MSVC 19.25编译时失败。 我的问题是:为什么编译器的行为不同?标准对此有何规定? 链接到编译器资源管理器: 叮当声https://godbolt.org/z/66M695 海湾合作委员会https://godbolt.or
在里面https://github.com/stlab/libraries/blob/main/stlab/concurrency/main_executor.hpp,我读到 decltype(f)的意义是什么,为什么不直接使用f?
(...)“m”不约束类型(...)
问题内容: 我的问题如标题中所述。我正在尝试做类似的事情: 我得到错误: 是否有其他方法可以在模板中进行模量计算? 问题答案: 添加具有所需逻辑的模板功能。例如: 游乐场的例子
问题内容: 我对棱角玉和玉都陌生。我想知道角度是否只能与HTML一起使用,还是可以在玉模板中使用相同的角度调用?我只看到有角度的模板与HTML一起使用,还没有在任何翡翠模板中找到它。有可能这样做吗?玉模板中的棱角看起来如何? 问题答案: 是的你可以。它看起来像:
我有以下问题:一个类模板a,有几个模板参数,我想构建一个类B,它以a为模板参数,并提取a的第一个模板参数,以便在某种方法中使用它(想想从std::vector 中提取int并返回默认的int{})。 我知道这种天真的方法不会编译,但我不知道如何实现这样的东西。感谢任何提示。