为什么 make_optional 不适用于文件流?
Why doesn't make_optional work for file streams?
我正在试用 C++17 可选类型,并认为使用它的合适位置是尝试打开文件的函数,可能returns打开的文件。我写的函数是这样的:
std::optional<std::fstream> openFile(std::string path)
{
std::fstream file;
file.open(path);
if (!file.is_open())
{
std::cerr << "couldn't open file" << path << std::endl;
return {};
}
else
{
return std::make_optional(file); // results in compilation error
}
}
但是,当我尝试使用 g++ 编译它并以 -std=c++17
作为参数之一时,我收到一大堆模板编译错误消息,从以下内容开始:
In file included from read_file.cpp:3:0:
/usr/include/c++/7/optional: In instantiation of ‘constexpr std::optional<typename std::decay<_Tp>::type> std::make_optional(_Tp&&) [with _Tp = std::basic_fstream<char>&; typename std::decay<_Tp>::type = std::basic_fstream<char>]’:
read_file.cpp:16:39: required from here
/usr/include/c++/7/optional:991:62: error: no matching function for call to ‘std::optional<std::basic_fstream<char> >::optional(<brace-enclosed initializer list>)’
{ return optional<decay_t<_Tp>> { std::forward<_Tp>(__t) }; }
为什么 fstream
似乎不能与 std::optional
一起使用?我是以错误的方式接近这个吗?如果 optional 不支持 stream-types,那不是限制了 type 可以应用的地方吗?
当您将流传递给 make_optional
时,您的代码将尝试复制流。流无法复制,因此需要移动它,即
return std::make_optional(std::move(file));
或者干脆
return file;
(根据编译器的年龄,后者可能不起作用。)
std::make_optional
以
的形式调用可选的构造函数
template < class U = value_type >
constexpr optional( U&& value );
并且该构造函数的行为与
相同
T optional_data = std::forward<U>(value)
因为你传递了一个左值,所以它会制作一个副本。流是不可复制的,所以你会得到一个错误。您必须 move
流进入可选的才能使其正常工作。
我正在试用 C++17 可选类型,并认为使用它的合适位置是尝试打开文件的函数,可能returns打开的文件。我写的函数是这样的:
std::optional<std::fstream> openFile(std::string path)
{
std::fstream file;
file.open(path);
if (!file.is_open())
{
std::cerr << "couldn't open file" << path << std::endl;
return {};
}
else
{
return std::make_optional(file); // results in compilation error
}
}
但是,当我尝试使用 g++ 编译它并以 -std=c++17
作为参数之一时,我收到一大堆模板编译错误消息,从以下内容开始:
In file included from read_file.cpp:3:0:
/usr/include/c++/7/optional: In instantiation of ‘constexpr std::optional<typename std::decay<_Tp>::type> std::make_optional(_Tp&&) [with _Tp = std::basic_fstream<char>&; typename std::decay<_Tp>::type = std::basic_fstream<char>]’:
read_file.cpp:16:39: required from here
/usr/include/c++/7/optional:991:62: error: no matching function for call to ‘std::optional<std::basic_fstream<char> >::optional(<brace-enclosed initializer list>)’
{ return optional<decay_t<_Tp>> { std::forward<_Tp>(__t) }; }
为什么 fstream
似乎不能与 std::optional
一起使用?我是以错误的方式接近这个吗?如果 optional 不支持 stream-types,那不是限制了 type 可以应用的地方吗?
当您将流传递给 make_optional
时,您的代码将尝试复制流。流无法复制,因此需要移动它,即
return std::make_optional(std::move(file));
或者干脆
return file;
(根据编译器的年龄,后者可能不起作用。)
std::make_optional
以
template < class U = value_type >
constexpr optional( U&& value );
并且该构造函数的行为与
相同T optional_data = std::forward<U>(value)
因为你传递了一个左值,所以它会制作一个副本。流是不可复制的,所以你会得到一个错误。您必须 move
流进入可选的才能使其正常工作。