Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/162.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 显式(bool)可以作用于字符文字参数的长度吗?_C++_Language Lawyer_C++20 - Fatal编程技术网

C++ 显式(bool)可以作用于字符文字参数的长度吗?

C++ 显式(bool)可以作用于字符文字参数的长度吗?,c++,language-lawyer,c++20,C++,Language Lawyer,C++20,我正在编写一个自定义字符串类,它将空间效率置于几乎所有其他考虑因素之上。它对6个字符或更少的字符串进行了小字符串优化,并对任何较大的字符串使用interning。下面有一个略显精简的版本 为方便起见,我希望有一个从字符串文本转换而来的构造函数,该构造函数仅在字符串文本足够短且适合sso缓冲区时隐式使用。对于较长的字符串,我希望构造函数是显式的,以防止由于实习的性能影响而意外使用它 在下面的代码中,我希望初始化Str b=not so short会导致编译器错误,因为条件显式说明符表达式为true

我正在编写一个自定义字符串类,它将空间效率置于几乎所有其他考虑因素之上。它对6个字符或更少的字符串进行了小字符串优化,并对任何较大的字符串使用interning。下面有一个略显精简的版本

为方便起见,我希望有一个从字符串文本转换而来的构造函数,该构造函数仅在字符串文本足够短且适合sso缓冲区时隐式使用。对于较长的字符串,我希望构造函数是显式的,以防止由于实习的性能影响而意外使用它

在下面的代码中,我希望初始化Str b=not so short会导致编译器错误,因为条件显式说明符表达式为true。但是,我在三个主要编译器中都没有发现错误。注意:Str a=短初始化工作正常

至少有一个编译器认为这应该像我预期的那样工作:VisualStudio的Intellisense功能使用的EDG前端给了我一个红色的曲线,错误是没有合适的构造函数可以将const char[13]转换为Str

Str班期末考试{ 公众: 使用value_type=char; 使用指针=值\类型常量*; 使用大小\类型=无符号长; //sso字符串的最大长度 静态自动constexpr ssoMaxLen=sizeofpointer-2; //从字符文本构造 样板 明确>ssoMaxLen+1 Strchar常量和str[N]; //从以零结尾的字符串(而不是文字)构造 显式Strpointer&&rstr; 大小\类型大小常数不例外; 私人: //唯一的非静态数据在此联合体中 联合{ 型积分; 指针式ptr; 值\类型文本[sizeofpointer]; }; //使用sso时文本成员中sso数据和大小的索引 //这假设了小endian 静态自动constexpr ssoData=1; 静态自动constexpr ssoSize=0; //实例数据不同部分的掩码 静态自动constexpr ssoSizeMask=sizeofpointer-1; 静态自动constexpr ssoDataMask=~ssoSizeMask; //执行长字符串的插入 静态指针InitLongpointer str,大小_类型len; }; 样板 Str::Strchar const&Str[N]{ //构造一个空字符串,如果长度为0,则返回 自动常数len=N-1; 如果len==0{ ptr=nullptr; 回来 } //如果长度足够长,进行实习并返回 如果len>ssoMaxLen{ ptr=InitLongstr,len; 回来 } //否则在sso模式下初始化 文本[ssoSize]=长度; text[ssoData+0]=str[0]; text[ssoData+1]=len>1?str[1]:0; text[ssoData+2]=len>2?str[2]:0; 如果constexpr ssoMaxLen>=3 text[ssoData+3]=len>3?str[3]:0; 如果constexpr ssoMaxLen>=4 text[ssoData+4]=len>4?str[4]:0; 如果constexpr ssoMaxLen>=5 text[ssoData+5]=len>5?str[5]:0; 如果constexpr ssoMaxLen>=6文本[ssoData+6]=0; } int main{ STRA=短; strb=不那么短; 返回a.size+b.size; } 这里有一个简短的提示:

using size_t = decltype(sizeof(0));

struct Str {
    template <size_t N>
    explicit(N > 7) Str(char const (&str)[N]);
};

#ifdef OUT_OF_LINE
template <size_t N>
Str::Str(char const(&str)[N]) { }
#endif

Str a = "short";
Str b = "not so short";
按原样,gcc和clang都正确地拒绝了。如果您定义了OUT OF OF LINE,则两个编译器都接受。存档和。

这里有一个简短的复制:

using size_t = decltype(sizeof(0));

struct Str {
    template <size_t N>
    explicit(N > 7) Str(char const (&str)[N]);
};

#ifdef OUT_OF_LINE
template <size_t N>
Str::Str(char const(&str)[N]) { }
#endif

Str a = "short";
Str b = "not so short";

按原样,gcc和clang都正确地拒绝了。如果您定义了OUT OF OF LINE,则两个编译器都接受。在写了所有这些之后,我意识到这太聪明了,也就是说太愚蠢了,我可能应该让构造函数无条件显式。不管怎样,我把这个问题留给别人,以防有人觉得有趣。我很想知道,在一个简单、无聊的std::字符串上使用它,你能从实际生活中获得什么好处?你真的能测量出真正不同的东西吗?如果是,在什么情况下?如果不是,为什么要麻烦呢?如果您的目标是在字符串对于SSO太长时禁用构造函数,那么您应该只使用SFINAE,而不是条件显式。我的意思是如果有人写得不短,那会发生什么?另一个问题是,为什么接受c字符串的字符串类的构造函数应该是显式的?@JesperJuhl我正在处理的当前测试用例显示了数百MB的内存使用量sizeofstd::string==sizeofStr*4。在一个我们有如此多的内存却只有如此少的钱的世界里,这种差异是否足够真实…,请回答。这段代码的90%是不相关的。在写了所有这些之后,我意识到这太聪明了,也就是说太愚蠢了,我可能应该让构造函数无条件显式。不管怎样,我把这个问题留给别人,以防有人觉得有趣。我很想知道,在一个简单、无聊的std::字符串上使用它,你能从实际生活中获得什么好处?你真的能测量出真正不同的东西吗?如果是,在什么情况下?如果不是,为什么要麻烦呢?如果你的目标是禁用co
如果字符串对于SSO来说太长,您应该简单地使用SFINAE,而不是条件显式。我的意思是如果有人写得不短,那会发生什么?另一个问题是,为什么接受c字符串的字符串类的构造函数应该是显式的?@JesperJuhl我正在处理的当前测试用例显示了数百MB的内存使用量sizeofstd::string==sizeofStr*4。在一个我们有如此多的内存却只有如此少的钱的世界里,这种差异是否足够真实…,请回答。此代码的90%与此无关。实现类定义的构造函数内联也适用于VC++,谢谢。实现类定义的构造函数内联也适用于VC++,谢谢。