在struct中使用constexpr方法进行模板参数化 [英] Using constexpr method for template parameterization inside struct
问题描述
这是我发现和描述的问题的延续。这里。
假设你有一个包含 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> constexprstruct 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 astd::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 errorfunction 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 withconstexpr
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 fromCount()
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 pointCount
has been declared but not yet defined, and aconstexpr
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屋!