微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

为什么这个编译器警告只显示 int 而不是 string? “在函数返回类型上忽略类型限定符”

如何解决为什么这个编译器警告只显示 int 而不是 string? “在函数返回类型上忽略类型限定符”

我对使用 mingw64 编译 C++11 代码时收到的一些警告感到有些困惑。这是我的 MWE:

class A{
    const string name;
    const int ID;

    public:
        A(string name_,int ID_) : name(name_),ID(ID_){
            // initialize non-const members
        }
        const string getName() const{return name;}
        const int getID() const{return ID;}
};

int main()
{   
    A aObj = A("Aname",1);
    std::cout << "getName() = " << aObj.getName() << std::endl;
    std::cout << "getID() = " << to_string(aObj.getID()) << std::endl;
}

代码执行得很好,并且执行了它应该做的事情,但是我收到了这个编译器警告:

,localtest.cpp:10:9: 警告:在函数返回类型上忽略类型限定符

[-Wignored-qualifiers] const int getID() const{return ID;}

所以警告只显示 getID() 而不是 getName(),即使两者具有相同的类型限定符。有人可以向我解释一下,为什么这个警告似乎只显示 string 而不是 int?我想这与 int 是原始数据类型有关 - 但究竟是什么?

解决方法

std::string 是一个具有可以是常量的成员函数的类。如果您有类的常量对象,则只能应用常量成员函数。

对于像 int 这样的基本类型,限定符 const 对返回值没有意义,因为在任何情况下都不能更改返回值。

这是一个演示程序

#include <iostream>
#include <string>

template <typename T>
const T f( const T &t )
{
    return t;
}

int main() 
{
    std::cout << f( std::string( "Hello World!" ) ).length() <<  '\n';

//  Invalid assignment  
//  f( 10 ) = 20;
    
    return 0;
}

程序输出为

12

如您所见,您可以将常量成员函数应用于 std::string 类型的返回对象(但您不能应用非常量成员函数)。并且您不能更改 int 类型的返回值。

,

考虑以下事项:

struct MyType {
  void foo() const;
  void bar();
};

MyType getMutable();
const MyType getConst();

int main() {
  getMutable().foo(); // fine
  getMutable().bar(); // fine
  getConst().foo(); // fine
  getConst().bar(); // Not allowed!
}

对于 int 没有任何等价物。您可以对 int RValue 执行的操作集与 const int RValue 完全相同。这就是您收到冗余警告的原因。

,

[expr.type]

如果纯右值最初的类型为“cv T”,其中 T 是一个 cv 未限定的非类、非数组类型,则在进一步分析之前,表达式的类型将调整为 T。

本质是:你可以有const类或数组类型的表达式,但不能有const原始类型的表达式。

,

由于 int 不是类,返回类型为 rvalue 就足以防止对返回对象的任何和所有修改。因此,

getInt(20) = 500;

不会是可编译的代码,并且没有您可以在 int 类型的对象上调用的成员。这就是为什么将 const 限定的内置类型作为返回值是没有意义的,并且编译器会警告您这一点。

但是对于班级来说情况有所不同。

getString("string").clear();

可能是有效或无效代码,取决于 getString 是返回非常量还是 const std::string 对象,因此编译器不会在后一种情况下发出警告。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其他元素将获得点击?
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。)
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbcDriver发生异常。为什么?
这是用Java进行XML解析的最佳库。
Java的PriorityQueue的内置迭代器不会以任何特定顺序遍历数据结构。为什么?
如何在Java中聆听按键时移动图像。
Java“Program to an interface”。这是什么意思?