如何对字符串和整数都具有隐式转换运算符?
简化代码:
#include <iostream>
#include <string>
struct Value
{
operator std::string() const { return "abc"; }
operator int() const { return 42; }
};
int main() {
Value v;
std::string s;
s = v; // error here
// lines below not really needed
int i;
i = v;
std::cout << s << " " << i << "\n";
}
c ++ 11编译器或更高版本。这些是错误,报告在字符串分配行上。
sandbox/casting_main.cpp: In function ‘int main()’:
sandbox/casting_main.cpp:14:7: error: ambiguous overload for ‘operator=’ (operand types are ‘std::__cxx11::string {aka std::__cxx11::basic_string<char>}’ and ‘Value’)
s = v; // error here
^
In file included from /usr/include/c++/5/string:52:0,
from /usr/include/c++/5/bits/locale_classes.h:40,
from /usr/include/c++/5/bits/ios_base.h:41,
from /usr/include/c++/5/ios:42,
from /usr/include/c++/5/ostream:38,
from /usr/include/c++/5/iostream:39,
from sandbox/casting_main.cpp:1:
/usr/include/c++/5/bits/basic_string.h:550:7: note: candidate: std::__cxx11::basic_string<_CharT, _Traits, _Alloc>& std::__cxx11::basic_string<_CharT, _Traits, _Alloc>::operator=(const std::__cxx11::basic_string<_CharT, _Traits, _Alloc>&) [with _CharT = char; _Traits = std::char_traits<char>; _Alloc = std::allocator<char>]
operator=(const basic_string& __str)
^
In file included from /usr/include/c++/5/string:52:0,
from /usr/include/c++/5/bits/locale_classes.h:40,
from /usr/include/c++/5/bits/ios_base.h:41,
from /usr/include/c++/5/ios:42,
from /usr/include/c++/5/ostream:38,
from /usr/include/c++/5/iostream:39,
from sandbox/casting_main.cpp:1:
/usr/include/c++/5/bits/basic_string.h:569:7: note: candidate: std::__cxx11::basic_string<_CharT, _Traits, _Alloc>& std::__cxx11::basic_string<_CharT, _Traits, _Alloc>::operator=(_CharT) [with _CharT = char; _Traits = std::char_traits<char>; _Alloc = std::allocator<char>]
operator=(_CharT __c)
^
In file included from /usr/include/c++/5/string:52:0,
from /usr/include/c++/5/bits/locale_classes.h:40,
from /usr/include/c++/5/bits/ios_base.h:41,
from /usr/include/c++/5/ios:42,
from /usr/include/c++/5/ostream:38,
from /usr/include/c++/5/iostream:39,
from sandbox/casting_main.cpp:1:
/usr/include/c++/5/bits/basic_string.h:587:7: note: candidate: std::__cxx11::basic_string<_CharT, _Traits, _Alloc>& std::__cxx11::basic_string<_CharT, _Traits, _Alloc>::operator=(std::__cxx11::basic_string<_CharT, _Traits, _Alloc>&&) [with _CharT = char; _Traits = std::char_traits<char>; _Alloc = std::allocator<char>]
operator=(basic_string&& __str)
^
显然,在c ++ 11标准中,有一个basic_string赋值运算符:
basic_string& operator=(charT c);
此赋值运算符引起编译器无法解决的歧义。
是否可以在同一个类中对字符串和int都使用隐式转换运算符?
答案 0 :(得分:0)
如果您查看basic_string
类,它会在分配operator=
的三个重载之后进行定义:
// 1. Rvalue reference overload for basic_string
basic_string& operator=(basic_string&& __str);
// 2. Lvalue Reference overload for basic_string
basic_string& operator=(const basic_string& __str);
// 3. Overload for type value_type (set as char, see std::string typedef below)
basic_string& operator=(value_type __c);
value_type
的定义如下:
template<class _CharT, class _Traits, class _Allocator>
class _LIBCPP_TEMPLATE_VIS basic_string
: private __basic_string_common<true>
{
public:
typedef _CharT value_type;
std::string
的定义为:
typedef basic_string<char, char_traits<char>, allocator<char> > string;
如您所见,在上述typedef中,_CharT
被设置为char
。现在,出现错误的行是:
s = v; // error here
问题在于,对于上述分配,所有三个basic_string
类型的运算符重载都是匹配的。
1.
和2.
重载匹配是因为您定义了从Value
到std::string
类型的隐式转换。 3.
重载匹配是因为从int
到char
的隐式转换,而Value
类型也隐含了对int
的转换。
这是因为这种含糊不清的分配是错误的。我想唯一的解决方法是从您的Value
类中删除一个隐式转换。
答案 1 :(得分:0)
这并不漂亮,但是可以使用SFINAE来完成。我们创建了一个模板转换运算符,但是限制为仅转换为int或std :: string,然后使用if constexpr
执行正确的行为。
#include <type_traits>
#include <iostream>
#include <string>
struct Value
{
template <typename type, typename = std::enable_if_t <std::is_same_v <type, std::string> || std::is_same_v <type, int>>>
operator type () const {
if constexpr (std::is_same_v <int, type>)
return 42;
else
return "abc";
}
};
int main() {
Value v;
std::string s;
s = v; // error here
// lines below not really needed
int i;
i = v;
std::cout << s << " " << i << "\n";
}