>免责声明:这将是蹩脚的。
两个问题:
-
由好奇心驱动的部分:带引号的字符串的确切类型是什么?以前我认为它是一个 C
char[]
字符串在需要时转换为std::string
,但一些type_traits
实验揭示了这一点:std::is_lvalue_reference<decltype ("string")>::value; -> true std::is_object<std::remove_reference<decltype ("string")>>::value; -> true std::is_same<decltype ("string"), std::string&>::value; -> false
-
蹩脚的部分:函数应该采用什么类型的参数才能处理像
fun("str")
这样的调用?这个问题的原因是以下示例由于static_assert
而无法编译:template <typename T> void fun (const T &what) { static_assert(sizeof(T) < 0, "Something unsupported"); } void fun (std::string str) { std::cout << "Copied" << std::endl; } void fun (const std::string &str) { std::cout << "Lvalue" << std::endl; } void fun (std::string &&str) { std::cout << "Rvalue" << std::endl; } int main () { fun ("str"); //static assertion failed return 0; }
此外,注释掉模板会导致
error: call of overloaded 'fun(const char [4])' is ambiguous candidates are: [all three options]
这对我来说似乎并不模棱两可。为什么它不构造一个临时字符串并通过右值引用传递它?
字符串文字"str"
的类型为 const char[4]
。此参数最合适的函数是模板函数,因为它不需要转换为 std::string。
以前我认为它是一个 C
char[]
字符串在需要时转换为std::string
关闭。这是一个在需要时转换为std::string
const char []
。
蹩脚的部分:函数应该采用什么类型的参数才能处理像
fun("str")
这样的调用?
您可以使用std::string
.您可以使用 const char (&) [N]
.您可以使用const char *
.然而。。。
这个问题的原因是以下示例由于
static_assert
而无法编译:
。你必须给重载解决一个机会。当你有
template <typename T> void fun (const T &what) { static_assert(sizeof(T) < 0, "Something unsupported"); }
那么即使字符串文字可以隐式转换为std::string
,你说这个函数可以直接接受字符串文字。当在隐式转换后采用字符串文字的函数和直接采用字符串文字的函数之间进行选择时,将调用直接采用字符串文字的函数。
此外,注释掉模板会导致
error: call of overloaded 'fun(const char [4])' is ambiguous candidates are: [all three options]
在按值和按引用之间选择。让单个非重载函数按值获取std::string
就可以了。让两个重载函数按const &
和&&
引用std::string
也可以。但是按价值和参考太多了,没有理由偏爱一个而不是另一个。