Overload resolution and arrays: which function should be called?

后端 未结 3 1533
你的背包
你的背包 2020-12-05 04:35

Consider the following program:

#include 
#include 

void f(char const*&&)      { std::puts(\"char const*&&\");          


        
3条回答
  •  暖寄归人
    2020-12-05 05:18

    I claim that #3 is the function chosen by a conforming compiler.

    (1) is better than (2) because "Standard conversion sequence S1 is a better conversion sequence than standard conversion sequence S2 if S1 and S2 are reference bindings (8.5.3) and neither refers to an implicit object parameter of a non-static member function declared without a ref-qualifier, and S1 binds an rvalue reference to an rvalue and S2 binds an lvalue reference."

    (3) is better than both (1) and (2) because it is an identity conversion (the others are exact match conversions) and "Standard conversion sequence S1 is a better conversion sequence than standard conversion sequence S2 if S1 is a proper subsequence of S2 (comparing the conversion sequences in the canonical form defined by 13.3.3.1.1, excluding any Lvalue Transformation; the identity conversion sequence is considered to be a subsequence of any non-identity conversion sequence)"

    Template vs non-template is only considered when neither conversion is better "or, if not that..."

    oddly enough though, Comeau prefers (2) over (3). This test case fails to compile:

    #include 
    #include 
    
    // (1) removed because Comeau doesn't support rvalue-references yet
    char f(char const* const&) { std::puts("char const* const&"); return 0; } // (2)
    
    template 
    int f(char const (&)[N])  { std::puts("char const(&)[N]"); return 0; } // (3)
    
    int main()
    {
        const char data[] = "a";
        switch (0) {
           case sizeof(char):
               break;
           case sizeof(f(data)):
               break;
        }
    }
    

提交回复
热议问题