문제

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?

도움이 되었습니까?

해결책

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;}
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top