考虑以下简单类 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, "");
}
Live Example仅在 Clang >= 3.4 上编译(因为它是唯一支持自动返回类型推导和宽松的 constexpr
函数的编译器)
gun()
类模板中的函数 Y<T>
(但不在类 X
内)生成编译器错误:
no return statement in constexpr function
问题:组合是constexpr
吗?具有自动推导的功能 void
根据标准不可能在类模板中返回类型,还是 Clang 中的编译器错误?
最佳答案
作为普通模板函数的解决方法,您可以:
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;}
关于c++ - 具有推导的 void 返回类型的 Constexpr 类模板成员函数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21440602/