使用 std::optional 个参数调用函数
Calling Functions With std::optional Parameters
我有一个函数,其签名是:
void func(std::optional<std::string> os = std::nullopt);
(在 std::optional
正式可用之前,我使用别名 std::experimental::optional
。)
但是,我很难把它叫清楚。编译器将拒绝执行两个隐式转换 (const char*
➝ std::string
➝ std::optional<std::string>
) 以使用原始 C 字符串文字调用它。我可以这样做:
func(std::string("Hello"));
并且编译器会认为需要 std::optional
并进行转换。但是,这太冗长了。感谢 C++11,我也可以这样做:
func({"Hello"});
虽然这好多了,但仍然不理想。我希望能够像调用任何其他需要 std::string
的函数一样调用此函数。 这可能吗? 让函数采用另一种参数类型是可以的,只要它的行为相似 to/is 可直接转换为 std::optional
。谢谢。
C++14 向标准库添加了一堆 user-defined 文字,以使代码不那么冗长。它看起来像这样:
using namespace std::string_literals; // needed
// using namespace std::literals; // also ok, but unnecessary
// using namespace std::literals::string_literals; // also ok, but why??
int main()
{
std::string str = "string"s;
^^^^^^^^
// This is a std::string literal,
// so std::string's copy constructor is called in this case
}
您可以使用一些模板和 sfinae 来做到这一点:
template<typename T, std::enable_if_t<
std::is_constructible<std::string, T>::value &&
!std::is_constructible<std::optional<std::string>, T>::value>* = nullptr>
void func(T&& s) {
void func(std::string(std::forward<T>(s)));
}
当字符串可以使用转发的 T
构造时,将选择此重载,但仅当 std::optional<std::string>
不可构造时。
你的函数可以用任何可以构造字符串的对象调用:
func("potato"); // working, forward the string literal to a std::string
我有一个函数,其签名是:
void func(std::optional<std::string> os = std::nullopt);
(在 std::optional
正式可用之前,我使用别名 std::experimental::optional
。)
但是,我很难把它叫清楚。编译器将拒绝执行两个隐式转换 (const char*
➝ std::string
➝ std::optional<std::string>
) 以使用原始 C 字符串文字调用它。我可以这样做:
func(std::string("Hello"));
并且编译器会认为需要 std::optional
并进行转换。但是,这太冗长了。感谢 C++11,我也可以这样做:
func({"Hello"});
虽然这好多了,但仍然不理想。我希望能够像调用任何其他需要 std::string
的函数一样调用此函数。 这可能吗? 让函数采用另一种参数类型是可以的,只要它的行为相似 to/is 可直接转换为 std::optional
。谢谢。
C++14 向标准库添加了一堆 user-defined 文字,以使代码不那么冗长。它看起来像这样:
using namespace std::string_literals; // needed
// using namespace std::literals; // also ok, but unnecessary
// using namespace std::literals::string_literals; // also ok, but why??
int main()
{
std::string str = "string"s;
^^^^^^^^
// This is a std::string literal,
// so std::string's copy constructor is called in this case
}
您可以使用一些模板和 sfinae 来做到这一点:
template<typename T, std::enable_if_t<
std::is_constructible<std::string, T>::value &&
!std::is_constructible<std::optional<std::string>, T>::value>* = nullptr>
void func(T&& s) {
void func(std::string(std::forward<T>(s)));
}
当字符串可以使用转发的 T
构造时,将选择此重载,但仅当 std::optional<std::string>
不可构造时。
你的函数可以用任何可以构造字符串的对象调用:
func("potato"); // working, forward the string literal to a std::string