将 out/in out 参数与 if/switch 的 init 语句一起使用
Using out/in-out parameters with init-statement for if/switch
我想使用带有"占位符"或类似内容的 if/switch 的 init 语句,这些参数作为 out-or in-out-parameter 传递给函数,例如。T f(X& x)
.
例如,std::filesystem
中的"全新"C++17 noexcept 重载使用 out 参数通过引用传递std::error_code
:
bool create_directory(const std::filesystem::path& p,
const std::filesystem::path& existing_p,
std::error_code& ec) noexcept;
或
void rename(const std::filesystem::path& old_p,
const std::filesystem::path& new_p,
std::error_code& ec) noexcept;
对于返回错误代码而不是将其作为 out 参数传递的函数,我会编写(伪代码(:
namespace fs = std::filesystem;
if (auto ec = fs::rename(old_p, new_p); ec)
{
// use ec handle error
} // ec's lifetime ends
相反,我不能在我的if
子句中将其与 init 语句一起使用:
namespace fs = std::filesystem;
std::error_code ec;
fs::rename(old_p, new_p, ec);
if (ec)
{
// handle error
}
// ec is still there
实际上,我通过使用包装器来保持调用者的代码干净,从而解决此问题:
namespace fs = std::filesystem;
inline std::error_code wrap_rename_ec(const fs::path& old_p,
const fs::path& new_p) noexcept
{
std::error_code ec;
fs::rename(old_p, new_p, ec);
return ec;
}
int main (void)
{
if (auto ec = wrap_rename_ec("old_p", "new_p"); ec)
{
// use ec to handle error
} // ec's lifetime ends
}
我会发现使用这样的东西(伪代码(很好:
namespace fs = std::filesystem;
if (std::error_code ec, fs::rename(old_p, new_p, ec); ec)
{
// handle error
} // ec's lifetime ends
我可以使用另一个重载的std::filesystem::rename
,它会在错误时抛出filesystem_error
,但是将现有路径或文件名作为新路径或文件名传递不一定是必须破坏程序中控制流的错误,我可能想附加" (2("或其他东西,因为我正在等待这种情况, 这也不例外。
旁注:我的问题不是讨论使用异常而不是错误代码,反之亦然。
我不确定在描述 if/switch 的 init 语句时是否考虑了我上面描述的情况,或者已经被丢弃了,而至少对我来说,找到一种优雅的方法会很好,没有包装函数处理 out/in-out-参数与 if/switch 的 init 语句。
TL;DR:从 if/switch 的 init-语句中获利与 out/in-out 参数相结合的最优雅方法是什么?可能吗?
问候 FA85
我会发现使用这样的东西(伪代码(很好:
using fs = std::filesystem; if (std::error_code ec, fs::rename(old_p, new_p, ec); ec) { // handle error } // ec's lifetime ends
你几乎猜到了正确的语法。
您正在寻找以下内容:
using fs = std::filesystem;
if (std::error_code ec; fs::rename(old_p, new_p, ec), ec) // Note that , and ; were switched.
{
// ...
}
另外,请注意,使用包装器会导致 UB 由于访问悬空引用:
using fs = std::filesystem;
inline std::error_code&& wrap_rename_ec(const fs::path& old_p,
const fs::path& new_p) noexcept
{
std::error_code ec; // Lifetime of `ec` ends after the function returns.
fs::rename(old_p, new_p, ec);
return std::move(ec);
}
正确的写法是:
using fs = std::filesystem;
std::error_code wrap_rename_ec(const fs::path& old_p,
const fs::path& new_p) noexcept
{
std::error_code ec;
fs::rename(old_p, new_p, ec);
return ec;
}
我认为你在问自己正确的问题。
init-语句的想法是初始化一个新变量。如果需要多个语句来初始化变量,则可能需要重构代码,而您所做的是一个选项。
所以这里有一个折衷方案:
-
你想要一些简洁的东西
-
您希望能够创建一个具有
if
或for
生存期的变量
委员会可能讨论过允许多个语句,但他们决定这会在不影响代码质量的情况下增加可读性(至少这是我的理解(。
不过,小错误:
return std::move(ec);
直接返回ec
,而不是按&&
,按值。编译器可能会告诉你很多。
- 我的简单if-else语句是如何无法访问的代码
- 有一个打印语句的函数是一种糟糕的编程实践吗
- 线程,如果else语句,都是错误的上下文切换后,会发生什么
- 为什么是0;C++中的有效语句
- Insert函数不适用于2 if语句C++
- If语句未被求值C++
- C++嵌套if语句,基本货币交换
- 多个If语句与使用逻辑运算符计算条件的单个语句的比较
- 是否可以使用if constexpr删除控制流语句
- 无法理解此 return 语句的功能,没有它就会发生运行时错误
- 我似乎对if/else的基本语句有问题:/
- 当调用switch语句中的函数时(即使函数不包含循环),似乎是永不结束的循环的问题
- If语句在c++中被忽略
- 比较if语句中的数组值和int值
- 以在Qt中的IF语句中设置时间延迟
- IN, OUT, INOUT Parameters
- Craps游戏问题,忽略if语句
- "类模板示例<int>;"语句对 C++11 是什么意思?
- 如何编写一个使用n倍三元条件语句的C++布尔函数
- 将 out/in out 参数与 if/switch 的 init 语句一起使用