簡體   English   中英

在C ++ 14中對此C ++ 17折疊表達式有什么好的替代方法?

[英]What is a good alternative to this C++17 fold expression in C++14?

這是C ++ 17中基於lambda的簡潔簡潔折疊表達式:

#include <cstdint>

using ::std::uint64_t;

constexpr auto sumsquares = [](auto... n) { return ((n * n) + ...); };

// I want this to work.
uint64_t foo(uint64_t x, uint64_t y, uint64_t z)
{
    return sumsquares(x, y, z);
}
// And this too
double bar(uint64_t x, double y)
{
    return sumsquares(x, y);
}

我已經編寫了這段代碼,以在C ++ 14中執行類似的操作,但是似乎比它應該的更加冗長和混亂。 我正在尋找一種以相對清晰簡潔的方式在C ++ 14中表達上述C ++ 17代碼的方法。 確切地說,我希望能夠編寫類似函數調用的語法,以計算一些已知維數的矢量的矢量幅度平方。 尺寸的數量可以任意變化。 坐標系統各個組成部分的精確數字類型也可以是任意的,也可能是異類的。 但是,在C ++ 14中處理C ++ 17折疊表達式的一般方法是理想的。

#include <cstdint>
#include <utility> 

using ::std::uint64_t;

namespace {
    static constexpr struct {
        template <typename T>
        auto operator()(T && n) const
        {
           return n*n;
        }
        template <typename T, typename... S>
        auto operator()(T && n, S && ... s) const
        {
            return (n * n) + (*this)(::std::forward<S>(s)...);
        }
    } sumsquares;
}

// I want this to work.
uint64_t foo(uint64_t x, uint64_t y, uint64_t z)
{
    return sumsquares(x, y, z);
}
// And this too
double bar(uint64_t x, double y)
{
    return sumsquares(x, y);
}
#include <utility>
#include <functional>

template<class F, class A0>
auto fold(F&&, A0&& a0) {
    return std::forward<A0>(a0);
}

template<class F, class A0, class...As>
auto fold(F&& f, A0&&a0, As&&...as) {
    return f(std::forward<A0>(a0), fold(f, std::forward<As>(as)...));
}

auto sum_squares=[](auto&&...args) {
    return fold(std::plus<>{}, (args * args)... );
};

下面是寫sum()一種可能的非遞歸方法:

template <typename ... Ts>
auto sum (Ts ... ts)
 {
   using unused = int[];

   std::common_type_t<Ts...>  ret {};

   (void)unused{ 0, (ret += ts, 0)... };

   return ret;
 }

給定sum()函數, sum_of_squares()可以簡單地編寫如下

template <typename ... Ts>
auto sum_of_squares (Ts ... ts)
 { return sum( (ts*ts)... ); }

是的,實際上,您可以通過在多個對象上定義一個通用總和來做得更簡單,更通用。

template<typename T>
T sum(T x)
{
    return x;
}
template<typename U, typename... T>
auto sum(U x, T... nums)
{
    return x + sum(nums...);
}

template<typename... T>
auto sum_of_squares(T... nums)
{
    auto square = [](auto x) { return x * x; };
    return sum(square(nums)...);
}

在此處進行實時演示在這里您可以看到生成的程序集(似乎是最佳的)。 雖然我個人確實不喜歡auto作為返回類型,但是在這里它可以避免獲取類型的非常復雜的表達式。

暫無
暫無

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

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