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

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

免责声明:这会变得蹩脚。

两个问题:

  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.

Prevoiusly I thought that it's a C char[] string converted to std::string when it is needed

关闭。它是 const char [] 在需要时转换为 std::string

The lame part: what type of argument should a function take to be able to deal with calls like fun("str")?

您可以使用 std::string。您可以使用 const char (&) [N]。您可以使用 const char *。然而...

The reason for this question is that the following example does not compile because of the static_assert:

...您必须给重载解析一个机会。当你有

template <typename T>
void fun (const T &what)
{
    static_assert(sizeof(T) < 0, "Something unsupported");
}

那么即使字符串文字可以隐式转换为 std::string,你说 this 函数可以直接接受字符串文字。当在隐式转换后采用字符串文字的函数和直接采用字符串文字的函数之间进行选择时,将调用直接采用它的函数。

More over, commenting the template out causes

error: call of overloaded 'fun(const char [4])' is ambiguous
candidates are: [all three options]

在按值获取和按引用获取之间进行选择。如果有一个非重载函数按值取 std::string 就好了。有两个重载函数也可以通过 const &&& 引用获取 std::string。但是按价值 按参考太多了,没有理由比另一个更喜欢一个。