如何在C++ 11中编写这个C++ 17 static constexpr方法?

Mat*_*att 0 c++ templates template-meta-programming c++11 c++17

static constexpr size_t Foo<>::sum()在C++ 11中编写下面的方法最简洁的方法是什么?这适用于C++ 17编译器,但我正在寻找一种适用于C++ 11模式的g ++,clang和Visual Studio 2015的方法.

#include <iostream>
#include <type_traits>

template<typename T,size_t N>
class Foo
{
  public:
    static constexpr size_t sum();
};

template<typename>
struct is_foo : std::false_type { };
template<typename T,size_t N>
struct is_foo<Foo<T,N>> : std::true_type { };

template<typename T,size_t N>
constexpr size_t Foo<T,N>::sum()
{
    if constexpr (is_foo<T>::value)
        return N + T::sum();
    else
        return N;
}

int main()
{
    constexpr size_t sum = Foo<Foo<Foo<double,3>,4>,5>::sum(); // 12 = 3+4+5
    std::cout << "sum = " << sum << std::endl;
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

编译并运行:

$ g++ --version
g++ (GCC) 7.3.1 20180303 (Red Hat 7.3.1-5)
...
$ g++ -std=c++17 sum.cpp
$ ./a.out 
sum = 12
Run Code Online (Sandbox Code Playgroud)

我能够写一个外部仿函数来sum()完成这个,但我真的希望它static constexpr成为上面的成员函数.这在C++ 11中甚至可能吗?

Hol*_*Cat 5

我写的如下:

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

template <typename T, size_t N>
struct foo_sum<Foo<T, N>> : std::integral_constant<size_t, foo_sum<T>::value + N> {};
Run Code Online (Sandbox Code Playgroud)

它可以static constexpr很容易地包装成一个函数:

template <typename T, size_t N>
constexpr size_t Foo<T, N>::sum()
{
    return foo_sum<Foo<T, N>>::value;
}
Run Code Online (Sandbox Code Playgroud)