【发布时间】:2018-01-09 09:04:47
【问题描述】:
在查看this 问题时,我用clang 进行了尝试,但遇到了一个奇怪的情况。下面的例子:
#include <string>
class ACP
{
public:
ACP() {}
operator const std::string() const { return std::string(); }
// operator std::string() const { return std::string(); } <-- makes clang happy
};
void test()
{
const ACP acp;
auto a = (std::string)acp;
}
使用 gcc 在 coliru 上编译良好,但由于 clang 失败。至少我认为这个例子没有问题 - 这是 clang 中的一个错误,还是有一个规则可以实际解释 clang 错误并且 gcc 是错误的?
clang 的错误如下所示:
clang -std=c++14 -O2 -Wall -pedantic -pthread main.cpp && ./a.out
main.cpp:13:26: error: no viable conversion from 'const ACP' to 'std::__cxx11::basic_string<char>'
auto a = (std::string)acp;
^~~
/usr/local/bin/../lib/gcc/x86_64-pc-linux-gnu/7.1.0/../../../../include/c++/7.1.0/bits/basic_string.h:421:7: note: candidate constructor not viable: no known conversion from 'const ACP' to 'const std::__cxx11::basic_string<char> &' for 1st argument
basic_string(const basic_string& __str)
^
/usr/local/bin/../lib/gcc/x86_64-pc-linux-gnu/7.1.0/../../../../include/c++/7.1.0/bits/basic_string.h:493:7: note: candidate constructor not viable: no known conversion from 'const ACP' to 'const char *' for 1st argument
basic_string(const _CharT* __s, const _Alloc& __a = _Alloc())
^
/usr/local/bin/../lib/gcc/x86_64-pc-linux-gnu/7.1.0/../../../../include/c++/7.1.0/bits/basic_string.h:515:7: note: candidate constructor not viable: no known conversion from 'const ACP' to 'std::__cxx11::basic_string<char> &&' for 1st argument
basic_string(basic_string&& __str) noexcept
^
/usr/local/bin/../lib/gcc/x86_64-pc-linux-gnu/7.1.0/../../../../include/c++/7.1.0/bits/basic_string.h:542:7: note: candidate constructor not viable: no known conversion from 'const ACP' to 'initializer_list<char>' for 1st argument
basic_string(initializer_list<_CharT> __l, const _Alloc& __a = _Alloc())
^
main.cpp:7:5: note: candidate function
operator const std::string() const { return std::string(); }
^
/usr/local/bin/../lib/gcc/x86_64-pc-linux-gnu/7.1.0/../../../../include/c++/7.1.0/bits/basic_string.h:515:35: note: passing argument to parameter '__str' here
basic_string(basic_string&& __str) noexcept
^
1 error generated.
但是我不明白为什么编译器不能使用来自 std::string 的复制 ctor。
【问题讨论】:
-
clang 在我看来有点可疑,但返回 const 对象可能是您的逻辑错误或误解。您确定不想返回对 const 字符串的引用吗?
-
std::string a = acp;而不是auto a = (std::string)acp;在 clang 中工作,如果这有任何帮助的话。 -
其实只要在操作符前面加上
explicit也让Clang开心...explicit operator const std::string() const { return std::string(); } -
这不是要求两个隐式的用户定义转换,而只允许一个?第一次转换
ACP->const std::string,第二次转换const std::string->std::string(通过复制构造函数) -
@RichardHodges 返回
const对象而不是非常量实际上是(曾经)Scott Meyer 推荐的做法,至少它适用于 C++03(如果我没记错的话)。
标签: c++ gcc clang language-lawyer