Функция-член шаблона класса Constexpr с выведенным пустым типом возврата?

Рассмотрим следующий простой класс X и шаблон класса Y<T> что каждый определяет четыре constexpr члены, три из которых имеют свои возвращаемые типы (новая функция C ++ 1y), и еще одно подмножество из трех, которое использует еще одну новую функцию C ++ 1y: расслабленную constexpr функция, которая теперь также может иметь побочные эффекты и void тип возврата.

Ниже приведен небольшой эксперимент по взаимодействию этих функций:

#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, "");
}

Живой пример который компилируется только на Clang> = 3.4 (потому что это единственный компилятор, который поддерживает как автоматическое возвращение типа возврата, так и ослабленный constexpr функции)

gun() функция внутри шаблона класса Y<T> (но не внутри класса X) генерирует ошибку компилятора:

нет оператора возврата в функции constexpr

Вопрос: это комбинация constexpr функция с автоматически выведенным void возвращаемый тип внутри шаблона класса невозможен в соответствии со Стандартом, или это ошибка компилятора в Clang?

5

Решение

В качестве обходного пути для нормальной функции шаблона вы можете сделать:

template<typename T> constexpr auto gun();
template<>
constexpr auto gun<void>() {}

Следуя той же логике, я думаю, что следующее не должно слишком сильно изменять ваш исходный код:

#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, "");
}

Также, как уже говорилось, пустой return заявление сделает свое дело.

constexpr auto gun() {return;}
1

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]