Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/150.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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/jsf-2/2.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++ 使用string#u视图构建istringstream不需要';不编译_C++_C++17 - Fatal编程技术网

C++ 使用string#u视图构建istringstream不需要';不编译

C++ 使用string#u视图构建istringstream不需要';不编译,c++,c++17,C++,C++17,我无法为std::istringstream的构造函数提供std::string\u视图。以下代码未编译(使用Clang v8启用了C++17): 我得到的错误是: prog.cc:9:24: error: no matching constructor for initialization of 'std::istringstream' (aka 'basic_istringstream<char>') std::istringstream ss(val, std::ios

我无法为
std::istringstream
的构造函数提供
std::string\u视图。以下代码未编译(使用Clang v8启用了C++17):

我得到的错误是:

prog.cc:9:24: error: no matching constructor for initialization of 'std::istringstream' (aka 'basic_istringstream<char>')
    std::istringstream ss(val, std::ios_base::in);
                       ^  ~~~~~~~~~~~~~~~~~~~~~~
/opt/wandbox/clang-6.0.0/include/c++/v1/sstream:651:14: note: candidate constructor not viable: no known conversion from 'std::string_view' (aka 'basic_string_view<char>') to 'const std::__1::basic_istringstream<char, std::__1::char_traits<char>, std::__1::allocator<char> >::string_type' (aka 'const basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >') for 1st argument
    explicit basic_istringstream(const string_type& __s,
             ^
这个问题对我来说很奇怪,因为这里应该只有一个隐式转换:
std::string\u view
std::basic\u string
。根据错误消息,构造函数正在获取一个
basic_字符串


为什么我不能在这里使用
string\u视图
而不调用
string\u视图::data()

这里的问题是,采用
std::string视图
std::string
构造函数被标记为
explicit
。这意味着您不能在隐式转换序列中使用它

您需要添加强制转换来显式转换它,或者改用
std::string
/
const char[]

这个问题对我来说很奇怪,因为这里应该只有一个隐式转换:
std::string\u view
std::basic\u string

string\u视图
不能隐式转换为
字符串
。构造函数(ok,演绎指南,但不管怎样)被标记为
显式

这应该有效(未经测试):


明确的原因是,这是一个(潜在的)昂贵的操作;涉及内存分配和数据复制。相反的转换(
string
-->
string\u view
)很便宜,因此是隐式的。

string\u view::data()
甚至不正确,因为stringstream需要一个以null结尾的字符串。我最近感觉到
string\u view
只会让事情变得比以前更复杂和混乱,因为事情要么是
std::string
要么是
char*
。到目前为止,我并不喜欢它。顺便说一句,您的“然而这确实”代码片段中有UB。构造函数将读取
字符串\u视图的结尾,查找空字符。如果它是显式的,这不是违背了目的吗?这基本上意味着您需要到处执行
std::string(val)
。我的想法是,隐式转换将是
std::string
std::string\u视图
之间优雅互操作性的关键。他们是否试图将更“浪费”的转换明确化,以避免意外地损害性能?@void.pointer。制作一个
std::string
可能需要分配,因此可能会很昂贵,应该仔细考虑。相反的转换虽然很便宜,但吐出
字符串视图
是可以的。(所以不喜欢简短的回答)值得注意的是,虽然这个“有效”,但它基本上违背了使用
std::string_view
的初衷。一个真正的答案需要像这样编写一个自定义streambuf:我不同意——但在C++20之前不行。在C++20中,
istringstream
将具有一个构造函数,该构造函数接受一个
字符串&
,并将其移动到流中;因此,保存分配/副本。
string\u视图
的用途远不止是
std::string
的替代表示形式。一个简单的例子是从一个大文本中提取一个子字符串,而不必复制它。关键是
istringstream
必须将字符复制到自身中。在C++17(及之前的版本)中,您必须创建一个字符串(复制),然后将它们再次复制到流中。在C++20中,流只需从
字符串&&
中移动其内部字符串,即可保存分配和副本。
prog.cc:9:24: error: no matching constructor for initialization of 'std::istringstream' (aka 'basic_istringstream<char>')
    std::istringstream ss(val, std::ios_base::in);
                       ^  ~~~~~~~~~~~~~~~~~~~~~~
/opt/wandbox/clang-6.0.0/include/c++/v1/sstream:651:14: note: candidate constructor not viable: no known conversion from 'std::string_view' (aka 'basic_string_view<char>') to 'const std::__1::basic_istringstream<char, std::__1::char_traits<char>, std::__1::allocator<char> >::string_type' (aka 'const basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >') for 1st argument
    explicit basic_istringstream(const string_type& __s,
             ^
std::string_view val = "Hello";
std::istringstream ss(val.data(), std::ios_base::in);
std::string_view val = "Hello";
std::istringstream ss(std::string(val), std::ios_base::in);