4

今天只想提一个问题,关于c++ 11(我用的是vs2010 sp1)中的C++模板函数参数推导和模板函数重载解析。我定义了两个模板函数,如下所示:

功能#1:

template <class T>
void func(const T& arg)
{
    cout << "void func(const T&)" <<endl;
}

功能#2:

template <class T>
void func(T&& arg)
{
   cout << "void func(T&&)" <<endl;
}

现在考虑以下代码:

int main() {
    //I understand these first two examples:

    //function #2 is selected, with T deduced as int&
    //If I comment out function #2, function#1 is selected with
    //T deduced as int
    {int a = 0; func(a);}

    //function #1 is selected, with T is deduced as int.
    //If I comment out function #1, function #2 is selected,
    //with T deduced as const int&.
    {const int a = 0; func(a);}

    //I don't understand the following examples:  

    //Function #2 is selected... why?
    //Why not function #1 or ambiguous...
    {func(0);}

    //But here function #1 is selected.
    //I know the literal string “feng” is lvalue expression and
    //T is deduced as “const char[5]”. The const modifier is part
    //of the T type not the const modifier in “const T&” declaration. 
    {func(“feng”)}

    //Here function#2 is selected in which T is deduced as char(&)[5]
    {char array[] = “feng”; func(array);}
}

我只想知道在这些场景下指导函数重载解析背后的规则。

我不同意下面的两个答案。我认为 const int 示例与文字字符串示例不同。我可以稍微修改一下#function 1,看看地球上的推断类型是什么

 template <class T>
 void func(const T& arg)
 {
    T local;
    local = 0;
    cout << "void func(const T&)" <<endl;
 }
 //the compiler compiles the code happily 
 //and it justify that the T is deduced as int type
 const int a = 0;
 func(a);

 template <class T>
 void func(const T& arg)
 {
T local;
Local[0] = ‘a’;
cout << "void func(const T&)" <<endl;
 }
 //The compiler complains that “error C2734: 'local' : const object must be     
 //initialized if not extern
 //see reference to function template instantiation 
 //'void func<const char[5]>(T (&))' being compiled
  //    with
  //    [
  //        T=const char [5]
  //    ]

 Func(“feng”);

在 const int 示例中,“const T&”声明中的 const 修饰符吃掉了 const int 的“常量性”;而在文字字符串示例中,我不知道“const T&”声明中的 const 修饰符在哪里。声明一些像int& const 是没有意义的(但是声明int* const 是有意义的)

4

2 回答 2

5

这里的诀窍是const. F1 和 F2 都可以接受任何类型的任何值,但 F2 通常是更好的匹配,因为它是完美的转发。因此,除非该值是const左值,否则 F2 是最佳匹配。但是,当左值为 时const,F1 是更好的匹配。这就是为什么它更适合 const int 和字符串文字的原因。

于 2012-09-04T07:48:30.317 回答
1

请注意,重载 #2 与 T& 和 T&& 完全匹配。所以这两个重载都可以绑定到右值和左值。在您的示例中,重载区分主要是在 constness 上完成的。

//Function #2 is selected... why?
//Why not function #1 or ambiguous...
{func(0);}

0is int&&- 完全匹配T&&

//But here function #1 is selected.
//I know the literal string “feng” is lvalue expression and
//T is deduced as “const char[5]”. The const modifier is part
//of the T type not the const modifier in “const T&” declaration. 
{func(“feng”)}

字面"feng" 量是const char(&)[5]- 与第一次重载完全匹配const T&(&)表示这是一个参考。

//Here function#2 is selected in which T is deduced as char(&)[5]
{char array[] = “feng”; func(array);}

数组 - 是- 与第二次重载char(&)[5]完全匹配T&

于 2012-09-04T08:10:42.610 回答