在声明和定义之间使用const限定符不一致 [英] Inconsistent use of const qualifier between declaration and definition

查看:165
本文介绍了在声明和定义之间使用const限定符不一致的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我注意到,可以在函数声明中存在的值参数上使用 const 限定词,然后在定义中省略。这不会改变函数的签名。它实际上编译得很好。

I noticed that it's possible to have const qualifier on a value argument present in the function declaration and then omitted in the definition. That doesn't change the signature of the function. It actually compiles well.

我也注意到,正常和模板类之间的行为是不同的。

I also noticed that the behavior is different between regular and template classes. Also there's a difference between how it's handled in GCC and Clang.

考虑下面的代码:

template <typename T> struct A {
    void f(const int);
};

template <typename T> void A<T>::f(int x) {
    x = 0;
}

struct B {
    void f(const int);
};

void B::f(int x) {
    x = 0;
}

void f() {
    A<float> a;
    a.f(0);

    B b;
    b.f(0);
}



当我用GCC编译时,我没有错误。使用Clang我得到:

When I compile with GCC I get no errors. With Clang I get:

test.cpp:10:7: error: read-only variable is not assignable
    x = 0;
    ~ ^
test.cpp:26:7: note: in instantiation of member function 'A<float>::f' requested here
    a.f(0);
      ^

GCC在定义时优先使用限定符。 Clang使用声明并且仅用于模板类 A

GCC took preference of the qualifier at the definition. Clang used the declaration and only for the template class A.

我的问题是:


  1. 这是由标准规范还是由此实施定义?

  2. 在常规和模板类之间是不同的吗?

  3. 为什么没有错误或者至少有一个警告: const

  1. Is this regulated by the standard or is this implementation defined?
  2. Why is the behavior is different between regular and template classes?
  3. Why is there no error or at least a warning that the const qualifier is used inconsistently between the declaration and the definition?
  4. Are there any situation where this could be useful?

更新:

根据评论,这似乎是一个ang错误。我打开了新订单

According to the comments it seems to be a Clang bug. I opened a new ticket.

更新:

错误已修复:


在r203741中修复

Fixed in r203741


推荐答案

此行为由标准定义,我可以告诉 gcc 在这里是正确的,如果我们看看草稿C ++标准部分 13.1 可重载声明 em> 3 说::

This behavior is defined by the standard and as far as I can tell gcc is correct here, if we look at the draft C++ standard section 13.1 Overloadable declarations paragraph 3 says:


[...] - 参数声明只在const的存在或不存在, /或易失性是等效的。也就是说,当确定正在声明,定义或调用哪个函数时,将忽略每个参数类型的const和volatile类型说明符。

[...]-Parameter declarations that differ only in the presence or absence of const and/or volatile are equivalent. That is, the const and volatile type-specifiers for each parameter type are ignored when determining which function is being declared, defined, or called.

并提供此示例:

[ Example:
    typedef const int cInt;

    int f (int);
    int f (const int); // redeclaration of f(int)
    int f (int) { /* ... */ } // definition of f(int)
    int f (cInt) { /* ... */ } // error: redefinition of f(int)
—end example ]

一些详细信息说明这仅适用于最外层的 cv限定符强调我):

and some details clarifying that that this applies only to the outermost cv qualifiers (emphasis mine):


只有在参数类型规范最外层的const和volatile类型说明符以这种方式被忽略;隐藏在参数类型规范中的 const和volatile类型说明符是重要的,可用于区分重载函数声明 123 特别是,对于任何类型T, T,指向const T的指针和指向volatile T的指针被认为是不同的参数类型,引用T,引用const T和引用
volatile T

Only the const and volatile type-specifiers at the outermost level of the parameter type specification are ignored in this fashion; const and volatile type-specifiers buried within a parameter type specification are significant and can be used to distinguish overloaded function declarations.123 In particular, for any type T, "pointer to T," "pointer to const T," and "pointer to volatile T" are considered distinct parameter types, as are "reference to T," "reference to const T," and "reference to volatile T."

,就我所知,这适用于模板类中的模板函数以及 14.8 具体> > >

and as far as I can tell this applies to template functions in template classes as well from section 14.8 Function template specializations specifically 14.8.3 Overload resolution which says:


[...]完整的候选函数集包括所有合成的声明和所有非模板重载的同名函数。除了13.3.3中明确指出的以外,合成的声明与其他重载解析的函数一样处理。 144

这篇关于在声明和定义之间使用const限定符不一致的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆