mardi 1 janvier 2019

How to write this C++17 static constexpr method in C++11?

What is the most concise way to write the below static constexpr size_t Foo<>::sum() method in C++11? This works fine with C++17 compilers, but I'm looking for a way that works on g++, clang, and Visual Studio 2015 in C++11 mode.

#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;
}

Compile and run:

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

I'm able to write an external functor for sum() that accomplishes this, but I would really like for it to be a static constexpr member function as above. Is this even possible in C++11?

Aucun commentaire:

Enregistrer un commentaire