传递 constexpr 对象
Passing constexpr objects around
我决定给constexpr
一个新的C++14
定义,为了充分利用它,我决定写一个小的编译时字符串解析器。但是,我正在努力使我的对象保持constexpr
,同时将其传递给函数。请考虑以下代码:
#include <cstddef>
#include <stdexcept>
class str_const {
const char * const p_;
const std::size_t sz_;
public:
template <std::size_t N>
constexpr str_const( const char( & a )[ N ] )
: p_( a ), sz_( N - 1 ) {}
constexpr char operator[]( std::size_t n ) const {
return n < sz_ ? p_[ n ] : throw std::out_of_range( "" );
}
constexpr std::size_t size() const { return sz_; }
};
constexpr long int numOpen( const str_const & str ){
long int numOpen{ 0 };
std::size_t idx{ 0 };
while ( idx < str.size() ){
if ( str[ idx ] == '{' ){ ++numOpen; }
else if ( str[ idx ] == '}' ){ --numOpen; }
++idx;
}
return numOpen;
}
constexpr bool check( const str_const & str ){
constexpr auto nOpen = numOpen( str );
// ...
// Apply More Test functions here,
// each returning a variable encoding the correctness of the input
// ...
return ( nOpen == 0 /* && ... Test the variables ... */ );
}
int main() {
constexpr str_const s1{ "{ Foo : Bar } { Quooz : Baz }" };
constexpr auto pass = check( s1 );
}
我使用Scott Schurr在C++Now 2012上提出的str_const
类,该类为C++14
进行了修改。
上面的代码将无法编译并显示错误(clang-3.5
(
error: constexpr variable 'nOpen' must be initialized by a constant expression
constexpr auto nOpen = numOpen( str );
~~~~~~~~~^~~~~
这使我得出的结论是,你不能在不失去其constexpr
性的情况下传递constexpr
对象。这让我想到以下问题:
我的解释正确吗?
为什么这是标准规定的行为?
我认为传递
constexpr
对象没有问题。当然,我可以重写我的代码以适应单个函数,但这会导致代码狭窄。我认为将单独的功能分解为单独的代码单元(函数(也应该是编译时操作的良好风格。正如我之前所说,编译器错误可以通过将代码从单独的测试函数(例如
numOpen
(的主体移动到顶级函数check
的主体来解决。但是,我不喜欢这个解决方案,因为它创建了一个巨大而狭窄的功能。你看到解决问题的不同方法吗?
原因是在
constexpr
函数中,参数不是常量表达式,无论参数是否是常量表达式。您可以在其他函数中调用constexpr
函数,但constexpr
函数的参数不会在内部constexpr
,这使得任何函数调用(甚至对constexpr
函数(都不是内部的常量表达式。
const auto nOpen = numOpen( str );
就足够了。只有当您从外部查看调用时,才会验证内部表达式的constexpr
性,从而决定是否constexpr
整个调用。
相关文章:
- Constexpr替代了新的放置方式,可以让内存中的对象保持未初始化状态
- 为什么我的 constexpr 对象在我的函数中不是 constexpr?
- 编译时生成应在构造函数中创建的非 constexpr 对象数组
- 为什么带有指针子对象的文字类类型的 constexpr 表达式不能是非类型模板参数
- 我可以制作一个std::set的constexpr对象吗
- 类本身内部的类对象的静态constexpr数组
- 使用 constexpr 初始化 std.array 中的对象
- l值引用对象上的Constexpr成员函数:Clang和gcc不同意
- constexpr函数可以返回本地对象的指针吗?
- 从“if constexpr”分支扩展对象生存期/范围
- 如果我的班级是字面的班级,那么将我的类的对象声明为constexpr是多余的
- static_assert HANA 教程中的非constexpr对象
- 有没有办法根据运行时值的类型返回 constexpr 对象
- constexpr引用非const对象
- 从 constexpr 返回对象?
- 使用方法失败更改constexpr对象成员
- 静态初始化包含功能指针的对象的constexpr std ::数组
- Lambda正在捕获constexpr对象
- 对于潜在的constexpr对象,所有比较运算符都是constexpr
- 在不创建参数对象的情况下解析constexpr函数