Как насчет специализации полного класса Foo
?
Вы также можете избежать is_foo
.
#include <iostream>
#include <type_traits>
template <typename, std::size_t N>
struct Foo
{ static constexpr std::size_t sum () { return N; } };
template <typename T, std::size_t N1, std::size_t N2>
struct Foo<Foo<T, N1>, N2>
{ static constexpr std::size_t sum () { return Foo<T, N1>::sum() + N2; } };
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;
}
- РЕДАКТИРОВАТЬ -
ОП спрос:
На практике Foo - это большой класс со многими функциями-членами.Требует ли это повторного определения их всех?
Не обязательно: вы можете сделать трюк с базовым классом / структурой Foo
(Bar
, в следующем примере)
#include <iostream>
#include <type_traits>
template <typename T, std::size_t N>
struct Foo;
template <typename, std::size_t N>
struct Bar
{ static constexpr std::size_t sum () { return N; } };
template <typename T, std::size_t N1, std::size_t N2>
struct Bar<Foo<T, N1>, N2>
{ static constexpr std::size_t sum () { return Foo<T, N1>::sum() + N2; } };
template <typename T, std::size_t N>
struct Foo : public Bar<T, N>
{ /* many common member and methods */};
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;
}