Constexpr class template member function with deduced void return type?
c++, c++11, c++14, constexpr, return-type-deduction
Solution
As a workaround for a normal template function, you can do:
template<typename T> constexpr auto gun();
template<>
constexpr auto gun<void>() {}
Following the same logic, I think the following should not change your original code too much:
#include <type_traits>
#include <utility>
struct X
{
constexpr auto gun() {}
};
template<class T>
struct Y
{
constexpr auto gun();
};
template<>
constexpr auto Y<X>::gun() { }
int main()
{
static_assert(std::is_same<void, decltype(std::declval<Y<X>>().gun())>::value, "");
}
Also as already stated, an empty `return` statement will do the trick.
constexpr auto gun() {return;}
Problem
Consider the following simple class `X` and class template `Y<T>` that each define four `constexpr` members, three of which have their return types deduced (new C++1y feature), and another subset of three that makes use of another new C++1y feature: the relaxed `constexpr` function that now also can have side-effects and a `void` return type. Below a small experiment with the interaction of these features: ``` #include <type_traits> #include <utility> struct X { constexpr void fun() {} // OK constexpr auto gun() {} // OK auto hun() {} // OK constexpr auto iun() { return 0; } // OK }; template<class T> struct Y { constexpr void fun() {} // OK //constexpr auto gun() {} // ERROR, why? auto hun() {} // OK constexpr auto iun() { return 0; } // OK }; int main() { static_assert(std::is_same<void, decltype(std::declval<X>().fun())>::value, ""); static_assert(std::is_same<void, decltype(std::declval<X>().gun())>::value, ""); static_assert(std::is_same<void, decltype(std::declval<X>().hun())>::value, ""); static_assert(std::is_same<int , decltype(std::declval<X>().iun())>::value, ""); static_assert(std::is_same<void, decltype(std::declval<Y<X>>().fun())>::value, ""); //static_assert(std::is_same<void, decltype(std::declval<Y<X>>().gun())>::value, ""); static_assert(std::is_same<void, decltype(std::declval<Y<X>>().hun())>::value, ""); static_assert(std::is_same<int , decltype(std::declval<Y<X>>().iun())>::value, ""); } ``` Live Example that only compiles on Clang >= 3.4 (because it is the only compiler that supports both the auto return type deduction and the relaxed `constexpr` functions) The `gun()` function inside the class template `Y<T>` (but not inside the class `X`) generates a compiler error: no return statement in constexpr function Question: is the combination a `constexpr` function with an automatically deduced `void` return type inside a class template not possible as per the Standard, or is it a compiler bug in Clang?