![](/img/trans.png)
[英]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.