是否有任何可能的方法来强制使用字符串文字进行隐式构造函数初始化
Posted
技术标签:
【中文标题】是否有任何可能的方法来强制使用字符串文字进行隐式构造函数初始化【英文标题】:Is there any possible way to force implicit constructor initialization with a string literal 【发布时间】:2014-04-12 03:11:30 【问题描述】:假设我有一堂课
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' 的无效转换 [-fpermissive]|
我能想到的只是制作一个额外的构造函数,它接受 char* 参数,但我希望避免这种冗余。
【问题讨论】:
这是一种不好的做法。应该避免这种隐式转换。 添加构造函数Foo(char const *s)
。在 C++11 中,您可以将其设为转发构造函数以避免代码重复:Foo(char const *s): Foo( std::string(s) )
【参考方案1】:
虽然看起来并不明显,但在复制初始化的情况下有两个用户定义的转换:
Foo f1 = "some string";
在上面的表达式中,Foo f1 =
是对Foo(Foo const &)
的调用,右侧作为参数。为此,编译器需要弄清楚如何从 literal(N 字符数组)到 Foo
,这需要用户定义转换为 std::string
(构造函数采用 const char*
) 和第二个用户定义的从std::string
到Foo
的转换(上面的第二个构造函数)。
现在,为什么第二种情况不需要相同数量的转换似乎并不明显……当您执行 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*
的构造函数。
【讨论】:
以上是关于是否有任何可能的方法来强制使用字符串文字进行隐式构造函数初始化的主要内容,如果未能解决你的问题,请参考以下文章