Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/150.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ const函数重载的行为_C++_Overloading - Fatal编程技术网

C++ const函数重载的行为

C++ const函数重载的行为,c++,overloading,C++,Overloading,我正在处理g++的问题,在这里我试图通过向参数添加const来重载函数。它工作正常,运行时调用函数时不使用const void print(const std::string& str){std::cout << "const" << str << std::endl;} void print(std::string& str){std::cout << str << std::endl;} int main() {

我正在处理g++的问题,在这里我试图通过向参数添加
const
来重载函数。它工作正常,运行时调用函数时不使用
const

void print(const std::string& str){std::cout << "const" << str << std::endl;}

void print(std::string& str){std::cout << str << std::endl;}

int main()
{
   std::string temp = "hello";
   print(temp);
   return 0;
}
是C++标准中指定的行为吗?<李>
  • 它调用函数而不使用
    const

    void print(const std::string& str){std::cout << "const" << str << std::endl;}
    
    void print(std::string& str){std::cout << str << std::endl;}
    
    int main()
    {
       std::string temp = "hello";
       print(temp);
       return 0;
    }
    

    void print(const std::string&str){std::cout,因为调用函数taking
    std::string const&
    需要两个隐式转换:一个到
    std::string const
    ,一个到
    std::string const&
    ;而调用函数taking
    std::string&
    只需要一个隐式转换(对于
    std::string&
    ),因此首选一个。

    参考绑定是身份类别§13.3.3.1.4),但由于后者更符合cv,因此对于§13.3.3.2,首选非常量(标准中的示例代码):


    这是标准行为。任何其他行为都会导致疯狂行为。特别是,非常量函数根本不可调用。

    常量是方法签名的一部分。重写仅适用于具有相同签名的方法。
    当您使用基类的const方法调用子类的not const方法时,此行为是为了避免出现相反的情况。

    原因是[over.ics.rank]/3中的这一节明确介绍了这种情况:

    标准转换顺序
    S1
    比 标准转换顺序
    S2
    if
    […]
    -
    S1
    S2
    为参考 绑定(8.5.3)和引用引用的类型是 相同类型,但顶级cv限定符和 由
    S2
    引用初始化的引用比 由
    S1
    初始化的引用所引用的类型

    S1
    对应于第二个重载,
    S2
    对应于第一个重载

    它调用函数而不使用
    const

    void print(const std::string& str){std::cout << "const" << str << std::endl;}
    
    void print(std::string& str){std::cout << str << std::endl;}
    
    int main()
    {
       std::string temp = "hello";
       print(temp);
       return 0;
    }
    

    您总是尝试选择最专业化的内容。重载解析就是这种情况,就像在函数模板的偏序中一样。第二个重载比第一个重载更专业化,因为第一个重载可以用参数调用,而第二个重载不能用参数调用-这是此规则背后的基本推理。

    O通过匹配参数的类型(包括限定符)进行过加载。在您的情况下,
    temp
    具有type
    std::string
    而不是
    const std::string
    。您只使用文字常量对其进行了初始化,它本身不是常量

    考虑以下几点:

    std::string temp( "hello" ) ;
    print(temp);                                    // hello   
    print( std::string("hello") ) ;                 // consthello
    print( "hello" ) ;                              // consthello
    print( static_cast<const std::string>(temp) ) ; // consthello
    
    const std::string temp2( "hello" ) ;
    print(temp2);                                    // consthello   
    

    但如果<代码>打印()>代码>试图修改对象,在这种情况下,结果是未定义的,所以认为实践不安全。< /P>


    使参数常量表示意图,允许编译器在代码试图修改对象或通过非常量参数将其传递给其他函数时发出诊断。它还可能为编译器提供优化的可能性。

    这很正常:您不使用常量对象调用它。请尝试使用
    const std::string temp=“你好”
    但是如果我删除了第二个函数。它会自动调用具有
    常量的函数。那么?好吧,
    temp
    不是
    常量,所以第二个版本比第一个版本更匹配。如果你只有一个版本,那么它显然是最好的匹配。@Nayanadassuriya:我已经明确说明了你的观察结果ns关于在我的回答中删除非常量版本(巧合而不是因为你问)。但对所有人来说,我们能否在评论中避免回答和提问?答案应作为答案发布,OP产生的问题应添加到原始问题中。但如果我删除了第二个函数。它会自动调用带有“const”的函数。那么?请注意我是如何说“首选”,而不是“无论是否存在任何其他过载,唯一的可能性是。"但是非常量函数匹配得更好。除了函数签名之外,编译器不知道非常量函数实际上没有修改参数,因此如果选择,它将选择非常量函数。如果没有选择,它将允许常量函数匹配。这是标准行为。好吧,我想复制构造函数是一个特例?bec因为在那里它使用
    const