考虑以下简单类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&gt; = 3.4(因为它是唯一支持自动返回类型演绎和宽松constexpr
函数的编译器)
类模板gun()
内的Y<T>
函数(但在类X
中不)会生成编译器错误:
constexpr函数中没有return语句
问题:是一个constexpr
函数与一个类模板中自动推导出的void
返回类型的组合,根据标准不可能,或者它是编译器错误在Clang?
答案 0 :(得分:1)
作为普通模板功能的解决方法,您可以执行以下操作:
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;}