在struct中使用constexpr方法进行模板参数化 [英] Using constexpr method for template parameterization inside struct

查看:574
本文介绍了在struct中使用constexpr方法进行模板参数化的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这是我发现和描述的问题的延续。这里



假设你有一个包含 static constexpr 函数的结构, std :: bitset (或任何你希望模板使用的const表达式的结果类型),如下:

  struct ExampleStruct {
static constexpr std :: size_t Count()noexcept {
return 3U;
}
使用Bitset = std :: bitset< Count()> ;;
}; Visual Studio 2015版本14.0.25029.00更新2 RC突出显示了 Count(),其中 调用为红色并生成错误函数调用必须在常量表达式中具有常量值



如何得到这个编译,或者获得类似的结果?



这里的错误到底是什么?编译器是否尝试在const表达式函数之前生成类型别名?



编辑:解释为什么这不工作可以在下面找到,没有人提供可能的解决方法,这里有一些我想出了:



(1)使用模板时,存储类型别名到

 模板< typename T> 
struct ExampleStruct {
使用ThisType = ExampleStruct< T> ;;
static constexpr std :: size_t Count()noexcept {
return 3U;
}
使用Bitset = std :: bitset< ThisType :: Count()> ;;
};

(2)移动 Count()外部的结构体。

  static constexpr std :: size_t Count()noexcept {
return 3U;
}

struct ExampleStruct {
using Bitset = std :: bitset< Count()>
};

(3)替换 constexpr code> constexpr 成员变量。

  struct ExampleStruct {
static constexpr std :: size_t Count = 3U;
using Bitset = std :: bitset< Count> ;;
};

(4)将值存储在 constexpr 变量,并从 Count()方法返回。

  struct ExampleStruct {
private:
static constexpr std :: size_t m_count = 3U;
public:
static constexpr std :: size_t Count()noexcept {
return m_count;
}
使用Bitset = std :: bitset< m_count> ;;
};


解决方案

您可能已经注意到,如果移动一个或两个线外的类体,错误消失。你遇到的问题是类成员函数定义(甚至是内联的)不会被解析,直到之后整个类定义已被解析;因此,当编译器使用Bitset = std :: bitset< Count()> ;; 时看到,此时 Count 已声明但尚未定义,并且未定义的 constexpr 函数不能在常量表达式中使用 - 因此您会看到错误。不幸的是,我知道没有好的解决方案或解决方法。


This is a continuation of the problem I found and described here.

Say you have a struct that contains a static constexpr function and a type alias for a std::bitset (or any type you wish to template using the result of the const expression) that looks as follows:

struct ExampleStruct {
    static constexpr std::size_t Count() noexcept {
        return 3U;
    }
    using Bitset = std::bitset<Count()>;
};

Visual Studio 2015 version 14.0.25029.00 Update 2 RC highlights the Count() call in red and generates the error function call must have a constant value in a constant expression.

How might one get this to compile, or achieve similar results?

What exactly is causing the error here? Is the compiler trying to generate the type alias before the const expression function?

EDIT: The explanation for why this does not work can be found below, but since no one provided possible workarounds, here are some that I came up with:

(1) When using templates, store type alias to this type.

template<typename T>
struct ExampleStruct {
    using ThisType = ExampleStruct<T>;
    static constexpr std::size_t Count() noexcept {
        return 3U;
    }
    using Bitset = std::bitset<ThisType::Count()>;
};

(2) Move Count() function outside of the struct body.

static constexpr std::size_t Count() noexcept {
    return 3U;
}

struct ExampleStruct {
    using Bitset = std::bitset<Count()>;
};

(3) Replace constexpr method with constexpr member variable.

struct ExampleStruct {
    static constexpr std::size_t Count = 3U;
    using Bitset = std::bitset<Count>;
};

(4) Store value in constexpr member variable, and return this from Count() method.

struct ExampleStruct {
private:
    static constexpr std::size_t m_count = 3U;
public:
    static constexpr std::size_t Count() noexcept {
        return m_count;
    }
    using Bitset = std::bitset<m_count>;
};

解决方案

You might have noticed that if you move one or both lines outside of the class body, the error goes away. The problem you're running into is that class member function definitions (even inline ones) are not parsed until after the entire class definition has been parsed; therefore, when the compiler sees using Bitset = std::bitset<Count()>;, at that point Count has been declared but not yet defined, and a constexpr function that has not been defined cannot be used in a constant expression -- so you get the error you're seeing. Unfortunately, I know of no good solution or workaround for this.

这篇关于在struct中使用constexpr方法进行模板参数化的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆