簡體   English   中英

帶有可變參數包的模板化可添加 class

[英]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中的運算符+未定義,其中_valstd::vector<int>us...值是int s。 所以錯誤。

例如,如果您使用單個參數調用add()

Addable<vector<int>>{v}.add(2)

代碼編譯(調用管理std::vector情況的add()版本)但顯然,當您運行編譯的程序時assert()失敗。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM