【发布时间】:2017-07-11 08:59:46
【问题描述】:
假设我想创建一个函数,它通过引用同时接受左值和右值字符串参数,将它们转换为大写,并将它们打印到标准输出:
void upper_print(std::string& s);
void upper_print(std::string&& s);
这可以正常工作,如下所示:
std::string s("Hello world");
upper_print(s);
upper_print(std::string("Hello world"));
upper_print("Hello world"); // converting ctor used
但是,为了避免冗余,我想改用转发引用:
template <typename T> upper_print(T&& s);
不幸的是,我无法使用字符串文字参数调用upper_print:
std::string s("Hello world"); // OK
upper_print(s); // OK
upper_print(std::string("Hello world")); // OK
upper_print("Hello world"); // ERROR
我知道将参数限制为 std::string 对象的可能性,例如,通过使用 std::enable_if 或 static_assert。但这在这里没有帮助。
在这个意义上,是否有任何选项可以结合转发引用和转换构造函数的功能?
【问题讨论】:
-
你想这样做的原因是什么?为什么不使用
const std::string &作为参数?它还有一个额外的好处是您将只有一个功能,而不是 3 个。 -
@geza 因为要转换字符串,您需要一个非常量字符串。
-
@RickAstley:这是一个很臭的设计。我不希望有一个名为
upper_print的函数修改字符串。我也找不到这个功能的好名字。 -
@geza:这只是一个 MWE。更一般地,转发引用结合了两个独立的属性:1)它们可以绑定到左值和右值,2)它们可以绑定到任何类型的对象。只有第一个引用也没有用吗?也就是说,可以绑定到左值和右值但仅限于特定类型的引用?
-
@geza:假设函数被称为
convert_to_upper_and_print。
标签: c++ implicit-conversion forwarding-reference