我有一个用户定义的文字运算符,只对特定长度的字符串有意义,如下所示:
constexpr uint16_t operator "" _int(const char* s, std::size_t len)
{
return len == 2 ? s[0] | (s[1] << 8) : throw;
}
这有效:
"AB"_int // equals 16961
但这也是编译,我不想要它:
"ABC"_int // throws at runtime
我尝试static_assert(len == 2)
,但在constexpr功能中不允许这样做。
如何让"ABC"_int
在编译时导致错误?
答案 0 :(得分:1)
如何让
"ABC"_int
在编译时导致错误?
通过示例:初始化constexpr
变量
constexpr auto foo = "ABC"_int;
否则(如果你不以某种方式强制编译时计算)编译器不会计算(不是强制的,但实际上是发生的事情)编译时,而是为运行时编译准备代码。
答案 1 :(得分:0)
#include <iostream>
#include <cstdint>
using namespace std;
constexpr uint16_t operator "" _int(char const * s, size_t len)
{
return (len == 2) ? s[0] | (s[1] << 8) : throw "len must be 2!";
}
int main()
{
constexpr uint16_t i1 = "AB"_int; // OK
cout << i1 << endl; // outputs 16961
constexpr uint16_t i2 = "ABC"_int; // error
cout << i2 << endl;
return 0;
}
prog.cpp: In function ‘int main()’:
prog.cpp:13:29: in constexpr expansion of ‘operator""_int(((const char*)"ABC"), 3ul)’
prog.cpp:7:52: error: expression ‘<throw-expression>’ is not a constant-expression
return (len == 2) ? s[0] | (s[1] << 8) : throw "len must be 2!";
^~~~~~~~~~~~~~~~
答案 2 :(得分:-1)
遗憾的是,这不适用于发表评论。
修复了使ungood文字成为编译时错误:
throw
。#include <iostream>
#include <stdint.h>
#include <limits.h> // CHAR_BIT
using namespace std;
using Byte = unsigned char;
const int bits_per_byte = CHAR_BIT;
static_assert( bits_per_byte == 8, "!" );
constexpr auto operator "" _int( char const* s, std::size_t len )
-> uint16_t
{ return len == 2 ? Byte( s[0] ) | (Byte( s[1] ) << 8u) : throw "Bah!"; }
#define CHAR_PAIR( s ) static_cast<uint16_t>( sizeof( char[s ## _int] ) )
auto main()
-> int
{
CHAR_PAIR( "AB" ); // OK
CHAR_PAIR( "ABC" ); //! Doesn't compile as ISO C++.
}
使用Visual C ++即可满足所有需要。
g ++在这方面不太符合标准,因此对于该编译器添加选项-Werror=vla
。
使用g ++,您也可以使用以下宏:
#define CHAR_PAIR( s ) []() constexpr { constexpr auto r = s##_int; return r; }()
这提供了更多信息性错误消息,但Visual C ++ 2017不支持。