gni*_*ola 7 c++ constructor c++11 c++14
在下面的示例中,我的输出是"single param ctor",两次.我的问题是双重的,首先,为什么叫而不是包含字符串版本的布尔构造函数,和第二,有没有办法让不叫铸造呼叫的字符串版本?
顺便说一句,我的实际代码不会使用硬编码字符串调用构造函数,而是使用以下内容:
static constexpr auto NONE = "NONE";
Foo aFoo(NONE);
Run Code Online (Sandbox Code Playgroud)
...
#include <iostream>
#include <string>
using namespace std;
struct Foo {
explicit Foo(bool _isVisible = false): id(""), isVisible(_isVisible) {cout << "single param ctor" << endl;}
explicit Foo(const string _id, bool _isVisible = false): id(_id), isVisible(_isVisible) {cout << "multip param ctor" << endl;}
const string id;
bool isVisible;
};
int main(int argc, const char * argv[]) {
shared_ptr<Foo> sharedFoo = make_shared<Foo>("hello");
Foo regFoo("hi");
return 0;
}
Run Code Online (Sandbox Code Playgroud)
这是继承自旧版C++并最终来自C的C++的限制.
您的字符串文字转换为bool优于"用户定义"类型std::string.
您可以添加一个构造函数,而不是在调用中进行转换const char*,可能会将其委托给您现有的构造函数,该构造函数包含std::string:
explicit Foo(const char* _id, bool _isVisible = false)
: Foo(std::string(_id), _isVisible)
{};
Run Code Online (Sandbox Code Playgroud)
这个构造函数将是"完全匹配"(或者无论如何足够接近)并且防止bool窃取风头.
或者,因为C++ 14,而不是投用的std::string文字,例如"hi"s,虽然你要记住,在这是一个通用的解决方案有点"咩"调用点做到这一点.
顺便说一下,如果你真的想std::string _id按值取你的参数,那就别做吧const; 你阻止它被移动,并在成员初始化器中需要一个副本.根据典型呼叫站点的情况,以下内容可能更有意义:
explicit Foo(
string _id,
bool _isVisible = false
)
: id(std::move(_id))
, isVisible(_isVisible)
{}
Run Code Online (Sandbox Code Playgroud)
但是,如果你通常传入左值,至少接受一个const std::string&以防止一个副本.