下面的示例代码旨在表达在其他代码的多个示例上实现2个目标的需要:
1.在模板函数bar
中维护完整的类型规范。
1.避免为bar
编写所有的 * l值 * 和 * r值 * 引用排列。
随着函数bar
中参数数量的增加,定义 * l值和r值引用 * 的每个排列变得更加困难。
目前,我无法在bar
函数中使用r值引用。
有没有我不知道的方法?或者我应该把每一个排列都写下来作为最后的手段?
Godbolt
#include <iostream>
#include <vector>
// Skip down to the bar function
template<typename DT> struct X
{
DT data;
X(DT data) : data(data * 2) {}
template<typename VT>
float foo(VT value) { return data + value; }
};
template<typename DT> struct Y
{
DT data;
Y(DT data) : data(data * 4) {}
template<typename VT>
float foo(VT value) { return value * data; }
};
template<typename DT> struct Z
{
DT data;
Z(DT data) : data(data * 8) {}
template<typename VT>
float foo(VT value) { return (value + 1) * (data + 1); }
};
// Function of interest
template <template<typename> typename XT, typename AT,
template<typename> typename YT, typename BT,
template<typename> typename ZT, typename CT>
float bar(XT<AT>&& a, YT<BT>&& b, ZT<CT>&& c) // Universal references are not allowed
{
XT<float> a_result(b.data - c.data);
YT<float> b_result(a.data - c.data);
XT<float> c_result(a.data + b.data);
return a_result.foo(a.data) + b_result.foo(b.data) + c_result.foo(c.data);
}
int main()
{
X<float> x(1.);
Y<double> y(2.);
Z<int> z(3);
double result = bar(x, y, z);
std::cout << result << std::endl;
}
以上代码的Godbolt输出
Could not execute the program
Compiler returned: 1
Compiler stderr
<source>: In function 'int main()':
<source>:52:23: error: cannot bind rvalue reference of type 'X<float>&&' to lvalue of type 'X<float>'
52 | double result = bar(x, y, z);
| ^
<source>:39:20: note: initializing argument 1 of 'float bar(XT<AT>&&, YT<BT>&&, ZT<CT>&&) [with XT = X; AT = float; YT = Y; BT = double; ZT = Z; CT = int]'
39 | float bar(XT<AT>&& a, YT<BT>&& b, ZT<CT>&& c) { // Universal references not allowed
| ~~~~~~~~~^
1条答案
按热度按时间jk9hmnmh1#
在所示的简化代码中,似乎只需要 *
const
限定的左值引用 *。但是,如果您坚持使用转发引用(àka.universal reference),我建议将模板的模板参数改为简单的模板函数,如下所示: