While working on a C++11 type-set, I tried to implement this function (stripped down to the minimum):
constexpr auto test() -> bool;
template <typename T, typename... Rest>
constexpr auto test() -> decltype(test<Rest...>())
{
return {};
}
Both gcc and clang choke on this. Clang says:
test.cpp:54:40: error: 'Rest' does not refer to a value
constexpr auto test() -> decltype(test<Rest...>())
^
gcc complains:
test.cpp:54:44: error: expected primary-expression before ‘...’ token
constexpr auto test() -> decltype(test<Rest...>())
I guess this is because the variadic version of test is not even fully declared when the decltype
looks at it.
However, when I use return type deduction in C++14, this compiles just fine:
constexpr auto test() -> bool;
template <typename T, typename... Rest>
constexpr auto test()
{
return test<Rest...>();
}
Seems like test
is considered sufficiently declared here.
I wonder why this doesn't work for the decltype
variant? Even if I turn on C++14 support?
PS: It turns out, that I cannot really call even the C++14 function, so maybe the whole thing is botched...
One problem is that your first test
overload is not a function template, so can't be called with test<>()
syntax.
However, decltype
doesn't really work with recursive variadic functions like that, since the return type is part of the declaration of the function, so that overload is not declared when the name is looked up.
You can get around this in C++11 by using template classes instead:
template <typename... Ts>
struct test;
template <typename T, typename... Ts>
struct test<T,Ts...> {
static decltype(test<Ts...>::value()) value() { return test<Ts...>::value(); }
};
template <>
struct test<> {
static bool value() { return true; }
};
Live demo
In C++14 you can make the first overload take a single template parameter and the second take two and a parameter pack:
template <typename T>
constexpr auto test() -> bool { return true; }
template <typename T, typename U, typename... Rest>
constexpr auto test()
{
return test<U,Rest...>();
}
Live demo
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With