[英]Deduce types pack from a variadic-templated class and declare an argument of the same types pack
[英]templated addable class with variadic pack
再会,
我尝试实现一个 class ,它可以使用内部存储变量_val
总结所有内容,见下文:
#include <utility>
#include <vector>
#include <cassert>
template <typename T>
class Addable {
T _val;
public:
explicit Addable(T v) :_val(std::move(v)) {}
template <typename ...Us>
[[nodiscard]] constexpr T add(Us&& ...us) const
{
return (_val + ... + us);
}
template<typename U>
[[nodiscard]] constexpr T add(U u) const
{
if constexpr (std::is_same_v<T, std::vector<U>>) {
auto copy = _val;
for (auto& n : copy) {
n += u;
}
return copy;
}
else {
return _val + u;
}
}
};
int main()
{
using namespace std;
assert(Addable<int>{42}.add() == 42);
assert(Addable<int>{42}.add(1) == 43);
assert(Addable<int>{42}.add(1, 1) == 44);
assert(Addable<int>{2}.add(1, 1, 1, 1, 1) == 7);
{
vector v {2, 3};
vector expected {3, 4};
assert(Addable<vector<int>>{v}.add(1) == expected);
}
{
vector v {2, 3};
vector expected {5, 6};
// assert(Addable<vector<int>>{v}.add(1, 2) == expected); // compile error...
}
return 0;
}
Class 工作 - 在这里使用带有简单T
的折叠表达式int
。 - 像std::vector
这样的T
但仅适用于一个U u
。
当我尝试 append 为每个向量元素一个来自可变参数包的每个元素时,我做错了什么?...
这个重载处理所有的测试用例:
template <typename ...Us>
[[nodiscard]] constexpr T add(Us&& ...us) const
{
if constexpr (!sizeof...(us))
{
return _val;
}
else if constexpr (std::is_same_v<T, std::vector< std::common_type_t<Us...> > > )
{ // [2]
auto copy = _val;
for (int& i : copy)
i += (us + ...);
return copy;
}
else
{
return (_val + ... + us);
}
}
在为T = vector
调用的 [2] 块中,您需要遍历副本中的所有项目,并且对于每个项目,您必须从输入 arguments 添加折叠结果(us +...)
。
当我尝试 append 为每个矢量元素一个来自可变参数包的每个矢量元素时,我做错了什么?..
我不明白你到底想要什么......无论如何
和
Addable<vector<int>>{v}.add(1, 2)
你用两个arguments 调用add()
。
您有两个版本的add()
:可变参数的版本和接收一个参数的版本。
所以,用两个arguments 调用它,只有可变参数匹配
template <typename ...Us>
[[nodiscard]] constexpr T add(Us&& ...us) const
{
return (_val + ... + us);
}
但是_val +... + us
中的运算符+
未定义,其中_val
是std::vector<int>
而us...
值是int
s。 所以错误。
例如,如果您使用单个参数调用add()
Addable<vector<int>>{v}.add(2)
代码编译(调用管理std::vector
情况的add()
版本)但显然,当您运行编译的程序时assert()
失败。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.