5

我有代码:

#include "stdafx.h"
#include <iostream>

using namespace std;


void func(const int& a)
{
    std::cout << "func(const)" << std::endl;
}

void func(volatile int& a)
{
    std::cout << "func(volatile)" << std::endl;
}

void func(const volatile int& a)
{
    std::cout << "func(const volatile)" << std::endl;
}

int main()
{
    const int a = 0;
    const volatile int b = 0;
    volatile int c = 0;
    func(a);
    func(b);
    func(c);
    system("pause");
    return 0;
}

上面的代码显示了基于参数是否为 const/volatile 的重载。但是,如果我将参数从 更改int&int,则代码将不再编译,并且我无法根据 const/volatile 参数类型重载。我不明白为什么如果 int 通过引用传递,我们可以基于 const 和 volatile 重载,但如果它通过值传递则不行?

编辑我应该强调我理解引用的作用-我不明白为什么允许引用别名在 const 上重载但普通的 int 不允许。

4

2 回答 2

13

问题是顶层const和/或volatile在重载解决方案中被忽略。所以

void foo(const int);

完全一样

void foo(int);

同样对于volatile. 这是一个语言规则,它是有意义的,因为参数是按值传递的。另一方面,引用const/volatile或指针const/volatile具有不同的含义:您不允许在它们所引用或指向的内容上调用非常量/易失性方法。在这里,const volatile它们不是顶级的。

void foo(int& i);       // can modify what i refers to, and this has effects outside of foo.
void foo(const int& i); // cannot modify what i refers to

上述两个声明具有非常不同的语义,因此语言使它们在重载解析方面有所不同。

于 2013-06-10T21:21:26.453 回答
4

也许从函数中退后一步,只看用例本身是有用的。

首先,我们将定义一个整数和一个常量整数,以在我们的示例中使用:

int       anInt     = 1;
const int aConstInt = 1;

接下来,我们看看使用这些变量设置其他整数和常量整数的值时会发生什么:

int       a = anInt;     // This works, we can set an int's value
                         //  using an int
int       b = aConstInt; // This works, we can set an int's value
                         //  using a const int
const int c = anInt;     // This works, we can set a const int's value
                         //  using an int
const int d = aConstInt; // This works, we can set a const int's value
                         //  using a const int

如您所见,没有办法根据行为来解决要选择的函数的哪个重载(一个 const int 可以被 int 和 const int 接受,同样一个 int 可以被 int 和 a常量整数)。

接下来,我们将看看将第一组变量传递给引用时会发生什么:

int& a = anInt;     // This works because we are using a
                    //  non-constant reference to access a
                    //  non-constant variable.
int& b = aConstInt; // This will NOT work because we are
                    //  trying to access a constant
                    //  variable through a non-constant
                    //  reference (i.e. we could
                    //  potentially change a constant
                    //  variable through the non-const
                    //  reference).

const int& c = anInt;     // This works because we are using a
                          //  constant reference (i.e. "I cannot
                          //  try to change the referenced
                          //  variable using this reference") to
                          //  a non-constant variable.
const int& d = aConstInt; // This will work because we are trying
                          //  to access a constant variable 
                          //  through a constant reference.

正如您所看到的,在区分 int 引用和 const int 引用时可能会产生一些有用的行为(即,当需要常量引用类型时,不允许创建非常量引用)。

于 2013-06-10T22:08:59.150 回答