c++ - 具有推导的 void 返回类型的 Constexpr 类模板成员函数?

标签 c++ c++11 constexpr c++14 return-type-deduction

考虑以下简单类 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/

相关文章:

c++ - 如何在 QListWidget 中为 QStringList 的每个项目显示一个 QLabel 和另一个 QString?

c++ - 空的括号初始化列表发出有关缺少字段初始化器的警告

C++ 为什么不能使用 constexpr 创建具有 const 引用成员变量的类?

c++ - 在编译时计算一个小整数的阶乘

C++11 constexpr 函数的参数传入模板参数

c++ - 引用静态常量数据对象

c++ - 为什么 std::string 不是 std::vector 的特化?

c++ - 在 VSCode 中只看到局部变量调试 C++

c++ - 当我们将指针从一个对象复制到同一类的另一个对象时,我们到底想要什么?

c++ - 使用 boost spirit qi 解析器解析枚举