I have a variadic template class SomeClass that looks like this (basically):
template<std::size_t SIZE_>
class SomeClass {
public:
static constexpr std::size_t SIZE = SIZE_;
};
It has a constexpr member that simply contains the std::size_t template parameter used to instantiate it. I want a constexpr function that can sum all the sizes of SomeClass<SIZE_> specializatins. My first idea was to make a simple variadic template function that adds all the SIZEs like that:
template<typename T>
constexpr std::size_t totalSize() {
return T::SIZE;
}
template <typename T, typename... Ts>
constexpr std::size_t totalSize() {
return totalSize<T>() + totalSize<Ts...>();
}
Now I try to call it:
constexpr std::size_t size = totalSize<SomeClass<1>, SomeClass<2>, SomeClass<3>>() // should return 6
It turns at that the last parameter unpacking makes call to totalSize<T> function ambiguous because both template totalSize functions match it. Fine, I modified my code to have two distinct functions and came up with this:
template<typename T>
constexpr std::size_t totalSizeSingle() {
return T::SIZE;
}
template <typename T, typename... Ts>
constexpr std::size_t totalSize() {
std::size_t result = totalSizeSingle<T>();
if (sizeof...(Ts) > 0) result += totalSize<Ts...>();
return result;
}
Again, the last unpacking seem to be problematic. Apparently, T can't be deduced even though it is known at compile time. I get the following error (compiling with GCC):
In instantiation of 'constexpr std::size_t totalSize() [with T = SomeClass<3>; Ts = {}; std::size_t = long long unsigned int]':
main.cpp:129:51: required from here
main.cpp:134:82: in 'constexpr' expansion of 'totalSize<SomeClass<1>, SomeClass<2>, SomeClass<3> >()'
main.cpp:129:51: in 'constexpr' expansion of 'totalSize<SomeClass<2>, SomeClass<3> >()'
main.cpp:129:58: error: no matching function for call to 'totalSize<>()'
129 | if (sizeof...(Ts) > 0) result += totalSize<Ts...>();
| ~~~~~~~~~~~~~~~~^~
main.cpp:127:23: note: candidate: 'template<class T, class ... Ts> constexpr std::size_t totalSize()'
127 | constexpr std::size_t totalSize() {
| ^~~~~~~~~
main.cpp:127:23: note: template argument deduction/substitution failed:
main.cpp:129:58: note: couldn't deduce template parameter 'T'
129 | if (sizeof...(Ts) > 0) result += totalSize<Ts...>();
| ~~~~~~~~~~~~~~~~^~
I don't really understand why it is not working. Every type is know at compile time. Why is this happening and how can I get it to work? I'm using C++11.