是否有任何可能的方法强制使用字符串文字进行隐式构造函数初始化

Is there any possible way to force implicit constructor initialization with a string literal

本文关键字:文字 字符串 初始化 构造函数 任何可 方法 是否      更新时间:2023-10-16

假设我有一个类

class Foo
{
public:
    Foo(int x);
    Foo(std::string s);
}

我希望能够初始化像这样的对象

int main()
{
    Foo f1 = "some string"
}

而不是

int main()
{
    Foo f1("some string");
}

到目前为止,我收到了一个编译器错误:错误:从"const char*"到"int"的转换无效[-fpermission]|

我所能想到的就是制作一个接受char*参数的额外构造函数,但我希望避免这种冗余。

虽然看起来不明显,但在副本初始化的情况下有两种用户定义的转换:

Foo f1 = "some string";

在上面的表达式中,Foo f1 =是对Foo(Foo const &)的调用,右手边作为自变量。为此,编译器需要弄清楚如何从literal(N个字符的数组)到Foo,这需要用户定义的到std::string的转换(采用const char*的构造函数)和第二个用户定义的从std::stringFoo的转换(上面的第二个构造函数)。

现在,为什么第二种情况不需要相同数量的转换似乎并不明显……当你执行Foo f("something");时,编译器会考虑三个重载:

Foo(int);
Foo(std::string);
Foo(Foo const &);

没有从字面到int的转换,因此第一个被丢弃。有一个从字面到std::string的一步转换(通过构造函数获取const char*),所以这是一个可行的候选者。如上所述,不存在从字面到Foo的一步转换,因此也会丢弃一个,而选择唯一可行的候选者。

这种语言非常清楚,因为在转换序列中只能有用户定义的转换,所以在那里什么都做不了。因此,您要么提供另一个构造函数,要么确保右侧std::string。为此,您可以显式转换(在C++03中有效):

Foo f1 = std::string("something");

您也可以将此问题留给用户,并要求他们进行直接初始化,而不是复制初始化。或者,您可以添加一个采用const char*的构造函数。