sizeof sum構造体を空のパラメーターパックで機能させるには


8

渡されたすべてのタイプのサイズの合計を決定するためのこの可変構造があります:

template <typename U, typename... T> struct TotalSizeOf 
    : std::integral_constant<size_t, sizeof(U) + TotalSizeOf<T...>::value> {};

template <typename U> struct TotalSizeOf<U> 
    : std::integral_constant<size_t, sizeof(U)> {};

使用法: TotalSizeOf<double, int, char>::value

問題は、これを変更して、空のパラメーターパックで動作し、戻ることができるようにする方法です0

例えば TotalSizeOf<>::value

現在、エラーが発生します error: wrong number of template arguments (0, should be at least 1)

C ++ 14しか使用できません。


デフォルトのテンプレート引数を定義して、sizeofに0を返すクラスを作成できますか?しかし、私は2番目は不可能だと思います。:たぶん、ここのような空の配列を持つstackoverflow.com/questions/47352663/...
RoQuOTriX

回答:


12

あなたも単にのために特化する必要があります <>

例:

template < typename... T> struct TotalSizeOf;

template < typename U, typename... T> struct TotalSizeOf<U, T...>
: std::integral_constant<size_t, sizeof(U) + TotalSizeOf<T...>::value> {};

template <> struct TotalSizeOf<> :
std::integral_constant<size_t, 0 > { };

int main()
{
    std::cout << TotalSizeOf< int, char>::value << std::endl;
    std::cout << TotalSizeOf< char>::value << std::endl;
    std::cout << TotalSizeOf< >::value << std::endl;
}

ありがとう、私はあなたのようにベースの非特化バージョンとしてトップラインを持っていなかったので、間違って特化していました。
サルガー

@Salgar:よくある失敗:-)これにより、「誤った数のテンプレート引数に特化」する結果になります...ところで:私もサンプルを実行したので、それに実行しました:-)
クラウス

5

C ++ 17では、折りたたみ式を使用して、複雑なテンプレートメタプログラミングをせずにこれを実現できます。

#include <iostream>
#include <type_traits>

template<class... T> 
struct TotalSizeOf: std::integral_constant<std::size_t, (0 + ... + sizeof(T))> {};

int main()
{
    std::cout << TotalSizeOf< int, char>::value << std::endl;
    std::cout << TotalSizeOf< char>::value << std::endl;
    std::cout << TotalSizeOf< >::value << std::endl;
}

これはコンパイル時にもより効率的になります(もちろん、実行時にはこれらは同じです)。

PS:読んでください、あなたはC ++ 14しか持っていませんが、これをここに置いておきます。新しいC ++バージョンで厄介なTMPを実行する必要が少なくなっているのは見た目が良いと思うので。

補遺:C ++ 17よりエレガントではありませんが、C ++ 14で、ほとんどtmp-freeです。

#include <iostream>
#include <type_traits>
#include <initializer_list>

constexpr size_t sum(std::initializer_list<size_t> arr) {
    // Accumulate is sadly not constexpr in C++14
    auto ret = 0ul;
    for(auto i: arr) {
        ret += i;
    }
    return ret;
}

template<class... T> 
struct TotalSizeOf: std::integral_constant<std::size_t, sum({sizeof(T)...})> {};

int main()
{
    std::cout << TotalSizeOf< int, char>::value << std::endl;
    std::cout << TotalSizeOf< char>::value << std::endl;
    std::cout << TotalSizeOf< >::value << std::endl;
}

1
はい、それは素晴らしいです。フォールド式を使用できることを楽しみにしています
サルガー
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.