2010-08-29 74 views
1

$ 10.3/5协变返回类型

“压倒一切的 函数的返回类型应是相同 重写的 功能或协变与类的功能 的返回类型。如果函数d ::˚F 覆盖了一个函数B :: f,其返回 类型的功能是协变 如果它们满足以下 标准:

- 无论是指针 类或引用classes98)

- 类B中的返回类型::˚F 是相同的类,如d :: f的 返回类型的类,或者是 明确的和可访问的直接或间接 基类中 返回类型d的::类F的

- 两个指针或引用具有 相同CV-资格的 类型中d的返回类型:: f 具有与0相同的cv资格在B :: f的返回类型中,比类 类型更少的cv资格。

struct A{}; 
struct B : A{}; 

struct X{ 
    virtual const A * const f(){return 0;} 
}; 

struct Y : X{ 
    virtual const B * volatile f(){return 0;} 
}; 

int main(){ 
    Y b; 
    X &r = b; 
    r.f(); 
} 

我写了上面的实验代码并发现科莫的错误/警告被inconsitent。第9行的警告似乎表明,返回类型的cv限定符没有意义。这就是导致代码格式不正确的原因。

"ComeauTest.c", line 5: warning: type qualifier on return type is meaningless 
virtual const A * const f(){return 0;} 
       ^

"ComeauTest.c", line 9: warning: type qualifier on return type is meaningless 
virtual const B * volatile f(){return 0;} 
       ^

"ComeauTest.c", line 9: error: return type is not identical to nor covariant with 
     return type "const A *const" of overridden virtual function function 
     "X::f" 
virtual const B * volatile f(){return 0;} 
         ^

所以,问题是,是科莫权在9行给予“警告”的消息?我知道这是一个实现定义的行为,而Comeau只是试图很好。但在这种情况下,它最容易混淆。

+1

我在错误信息中看到volatile,但在示例源代码中看不到。您正在向我们显示您正在编译的代码的代码? – Thanatos 2010-08-29 05:13:06

+0

@Thanatos:我经过OP – Chubsdad 2010-08-29 05:15:41

+0

+1之后纠正了它,詹姆斯是我见过的最晦涩的角落案例。 – Potatoswatter 2010-08-29 07:09:18

回答

2

第5行和第9行的警告“返回类型的类型限定符是无意义的”是因为非类类型的rvalues永远不符合cv。

由于按值返回的函数的结果是一个右值并且指针是非类类型,所以即使返回类型说明它返回的指针也不是cv限定的。

此警告与协方差无关。从10.3/10

int* volatile f() { return 0; } 

至于引用文本:下面的函数会导致相同的警告

两个指针或引用具有相同的CV-资格

这是指的是返回类型的顶级资格(即,const int* volatile)。而顶层的资格是没有意义的,它影响功能的类型,所以给定的f的声明之上,此片段是不正确的:

int* (*q)() = f; // error: can't convert int* volatile (*)() to int* (*)() 

同样地,如果顶级CV-资格派生类成员函数中的返回类型与基类中返回类型的顶级cv-qualification不匹配,则派生类成员函数不会覆盖基类成员函数。

D::f返回类型的类类型具有相同的CV-资格或更少CV-资格比在B::f返回类型的类类型。

这指的是类的类型的返回值的资格(即,在const int* volatileconst)。此规则意味着派生类成员函数中返回类型的限定必须等于或小于其重写的基类成员函数的返回类型的限定。

+0

如何解释协方差条件的第三个子句中的两个“粗体”部分,特别是条件的第二部分? – Chubsdad 2010-08-29 05:20:15

+0

如果'确实影响函数的类型',我认为Comeau的警告消息在这种情况下可能不正确。或者不是? – Chubsdad 2010-08-29 05:35:15

+0

@chubsdad:'f'(它是'int * volatile')的返回类型和rvalue函数调用表达式'f()'(它是'int *')的类型之间是有区别的。 Comeau警告你,对于后一种情况,最高级的cv-qualifier是没有意义的。 – 2010-08-29 05:59:41