简体   繁体   English

C ++:使用委托构造函数时选择`const char *`vs`std :: string`

[英]C++: choosing a `const char *` vs `std::string` when using delegating constructor

Consider the following: 考虑以下:

class Foo {
public:
    Foo (const char *in) {
        printf ("C string constructor called\n");
    }
    Foo (std::string const &in) : Foo(in.c_str()) {
        printf ("C++ string constructor called\n");
    }
};
Foo bar ("I never asked for this");
//C string constructor called

So, a constant string is treated as a const char * one. 因此,常量string被视为const char * one。

But what would change, if we make a std::string constructor "primary"? 但是,如果我们将std::string构造函数std::string “ primary”,会发生什么变化呢?

Can we expect that an std::string object would be created and passed to corresponding constructor without calling a C-string related one? 我们是否可以期望将创建一个std::string对象并将其传递给相应的构造函数,而无需调用与C字符串相关的对象?

class Foo {
public:
    Foo (std::string const &in) {
        printf ("C++ string constructor called\n");
    }
    Foo (const char *in) : Foo(std::string (in)) {
        printf ("C string constructor called\n");
    }
};
Foo bar ("I never asked for this");
//C++ string constructor called
//C string constructor called

Again, the C-string constructor was called first . 同样,C字符串构造函数被称为first

Is this behavior described in C++ standard, or is it compiler-related? 是在C ++标准中描述了此行为,还是与编译器相关?

Would this work the same way for eg templates or overloaded functions? 对于模板或重载函数,这将以相同的方式工作吗?

I compiled with GCC 7.3.0 (MSYS2 x64). 我使用GCC 7.3.0(MSYS2 x64)进行了编译。

"I never asked for this" is a string literal which consists of const char elements: "I never asked for this"是一个字符串常量 ,由const char元素组成:

Foo bar ("I never asked for this"); // calls Foo (const char *in)

Thus, Foo (const char *in) will always get selected by overload resolution regardless of the "order" in which you declare your constructors. 因此, 无论声明构造函数的“顺序” 如何Foo (const char *in)始终会被重载解析选择

As seen in your 2nd example, 如您第二个示例所示,

Foo (const char *in) : Foo(std::string (in))

The delegating constructor is selected and will call the target constructor , as selected by the only member of the initialization list. 委派了构造函数 ,并且将调用目标构造函数 ,这是由初始化列表的唯一成员选择的。

There is no such thing as primary constructor in C++. C ++中没有像构造函数这样的东西。

What you observe is that the delegated to constructor ( target constructor ) body is executed first. 您观察到的是,首先执行了委托给构造函数( 目标构造函数 )的主体。 Then the body of the constructor that delegates ( delegating constructor ). 然后是委托的构造函数的主体( delegating constructor )。

Delegating constructor : 委托构造函数

In this case, the target constructor is selected by overload resolution and executed first, then the control returns to the delegating constructor and its body is executed. 在这种情况下,将通过重载决议选择目标构造函数并首先执行它,然后控件返回到委派构造函数,并执行其主体。

Overload Resolution and Constructor Delegation are two completely different things that do not influence each other at all. 重载解析构造函数委派是两个完全不同的事物,它们根本不会相互影响。

Overload Resolution avoids implicit conversions when possible. 重载解析避免了可能的隐式转换。

A string literal like "I never asked for this" is a const char[] , which decays to const char * . "I never asked for this"这样的字符串文字是const char[] ,它会衰减为const char * That is an exact match for your const char * constructor, so that is the one that gets called. 这与您的const char *构造const char *完全匹配,因此被调用。 Calling your std::string constructor with a string literal as input would require an implicit conversion, as the compiler would have construct a temporary std::string object to bind to the std::string const & reference. 用字符串文字作为输入来调用std::string构造函数将需要进行隐式转换,因为编译器将构造一个临时的std::string对象以绑定到std::string const & reference。

Had you written this code instead: 您是否编写了此代码:

Foo bar (std::string("I never asked for this"));

Or this: 或这个:

std::string str = "I never asked for this";
Foo bar (str);

Then the std::string const & constructor would be called instead of the const char * constructor, as there is no implicit conversion from std::string to const char * . 然后将调用std::string const &构造std::string const &而不是const char *构造函数,因为没有从std::stringconst char *隐式转换。

How constructors delegate to each other is an implementation detail AFTER the compiler decides which constructor to call. 在编译器决定调用哪个构造函数之后构造函数如何相互委托是一个实现细节

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM