Alex Rivera | Logout

Overload resolution and arrays: which function should be called?

Asked 2011-03-18T02:33:18.137
30

Consider the following program:

#include <cstddef>
#include <cstdio>

void f(char const*&&)      { std::puts("char const*&&");      } // (1)
void f(char const* const&) { std::puts("char const* const&"); } // (2)

template <std::size_t N>
void f(char const (&)[N])  { std::puts("char const(&)[N]");   } // (3)

int main()
{
    const char data[] = "a";
    f(data);
}

Which f should be called? Why?

The latest released versions of three compilers disagree on the answer to this question:

  • (1) is called when the program is compiled using g++ 4.5.2
  • (2) is called when the program is compiled using Visual C++ 2010 SP1
  • (3) is called when the program is compiled using Clang 3.0 (trunk 127530)

Have the overload resolution rules changed substantially in different C++0x drafts? Or, are two of these compilers really just completely wrong? Which overload is the correct overload to be selected per the latest C++0x draft?

Edit
Report

1 Answer

2

This is a community wiki answer for collecting snippets from the standard (draft 3225).

section 13.3.3 "Best viable function" [over.match.best]

  1. Define ICSi(F) as follows:

    • if F is a static member function, ICS1(F) is defined such that ICS1(F) is neither better nor worse than ICS1(G) for any function G, and, symmetrically, ICS1(G) is neither better nor worse than ICS1(F); otherwise,

    • let ICSi(F) denote the implicit conversion sequence that converts the i-th argument in the list to the type of the i-th parameter of viable function F. 13.3.3.1 defines the implicit conversion sequences and 13.3.3.2 defines what it means for one implicit conversion sequence to be a better conversion sequence or worse conversion sequence than another.

    Given these definitions, a viable function F1 is defined to be a better function than another viable function F2 if for all arguments i, ICSi(F1) is not a worse conversion sequence than ICSi(F2), and then

    • for some argument j, ICSj(F1) is a better conversion sequence than ICSj(F2)

    or, if not that,

    • the context is an initialization by user-defined conversion (see 8.5, 13.3.1.5, and 13.3.1.6) and the standard conversion sequence from the return type of F1 to the destination type (i.e., the type of the entity being initialized) is a better conversion sequence than the standard conversion sequence from the return type of F2 to the destination type

    or, if not that,

    • F1 is a non-template function and F2 is a function template specialization

    or, if not that,

    • F1 and F2 are function template specializations, and the function template for F1 is more specialized than the template for
answered 2011-03-18T02:52:29.133

Your Answer