C++:"such strings"类型。使像 fun( "str" ) 一样的函数调用工作

C++: type of "such strings". Making a function call like fun("str") work

本文关键字:工作 函数调用 str 一样 fun such strings 类型 使像 C++      更新时间:2023-10-16

>免责声明:这将是蹩脚的。

两个问题:

  1. 由好奇心驱动的部分:带引号的字符串的确切类型是什么?以前我认为它是一个 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
    
  2. 蹩脚的部分:函数应该采用什么类型的参数才能处理像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也可以。但是按价值参考太多了,没有理由偏爱一个而不是另一个。