【问题标题】:Implicitly convertible argument, but of ref type隐式可转换参数,但属于 ref 类型
【发布时间】:2020-09-07 22:31:49
【问题描述】:
#include <iostream>
#include <string>

void foo(const std::string & s)
{
    std::cout << s;
}

const char * text = "something";


int main()
{
    foo( text );
}

我开始想知道这里发生了什么,因为gdb 报告s == ""。根据最近的(比如C++17)版本的标准应该发生什么?

通过https://godbolt.org/ 我可以看到一个std::string c-tor,所以也许一个是通过引用构造和传递的,然后在函数终止时销毁。

【问题讨论】:

  • “gdb 报告s == ""”是什么意思?应该发生的事情是程序输出“某事”。如果您在调试器的幕后窥视,是否观察到任何特定的事情不在标准范围内。

标签: c++ constructor pass-by-reference implicit-conversion temporary-objects


【解决方案1】:

类模板std::basic_string具有隐式转换构造函数

basic_string(const charT* s, const Allocator& a = Allocator());

所以在这次通话中

foo( text );

一个std::string 类型的临时对象被创建,并且对它的引用被用作函数参数的初始化器。在此语句的最后,临时对象被销毁。

这是一个演示程序,它使用示例类显示幕后发生的事情。

#include <iostream>

class String
{
private:
    const char *s;

public:
    String( const char *s ) :s( s ) 
    {
        std::cout << "String( const char * ) is called\n";
    }

    ~String()
    {
        std::cout << "~String() is called\n";
    }

    friend std::ostream & operator <<( std::ostream &os, const String & s )
    {
        return os << s.s;
    }
};

void foo( const String & s )
{
    std::cout << s << '\n';
}

const char * text = "something";


int main()
{
    foo( text );
} 

程序输出是

String( const char * ) is called
something
~String() is called

如果使用函数说明符 explicit 声明构造函数,则程序将无法运行。

    explicit String( const char *s ) :s( s ) 
    {
        std::cout << "String( const char * ) is called\n";
    }

要使程序运行,您需要显式调用构造函数。例如

foo( String( text ) );

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-12-27
    • 2013-07-09
    • 1970-01-01
    相关资源
    最近更新 更多