我能够找到大量关于从int到用户定义类型的隐式转换的信息。即如果构造函数将int作为其参数并且不以“explicit”开头,则可能发生隐式转换。
如果我希望我的类隐式将转换为一个int?
,该怎么办?例如,需要在SimpleClass内部或外部添加什么函数,以便main函数将编译并输出“1”到控制台? (见评论)
#include <iostream>
class SimpleClass
{
private:
int m_int;
public:
SimpleClass(int value)
: m_int(value) {}
};
int main(int argc, const char * argv[])
{
SimpleClass simpleclass(1);
int i = simpleclass; // does not complile
std::cout << i << std::endl; // should output "1" to the console
return 0;
}
答案 0 :(得分:11)
隐式转换可以通过两种方式定义:
后者允许定义从类类型到基本类型的转换。只需添加
class SimpleClass {
// ...
operator int() const;
};
SimpleClass::operator int() const
{
return m_int;
}
答案 1 :(得分:6)
转换为(几乎)任何类型T
都可以由operator T
成员函数执行。
默认情况下会隐式调用它,如果您声明它const
,也可以在const
对象上调用它。
因此:
struct MyType
{
operator int() const { return 1; }
};
隐式转换为基本类型允许所有内置运算符的自由播放,包括
因此,您最好确保所有以您想要的方式运作。
这可能是很多工作!
对于涉及您的类型实例的调用,重载解析也存在潜在问题。
简而言之,隐式转换为int
,指针或任何内置类型,通常会花费超过它的价值。
值得一提的例外是在库中使用很多类时。
避免隐式转换,但确实提供了显式转换。
最好的一般显式转换是,恕我直言,一个命名成员函数。
另一种选择是前缀为operator T
的{{1}},在C ++ 11及更高版本中支持此用法(在C ++ 03中它只能用于构造函数)。
如果您希望通过explicit
输出的行为就像执行隐式转换一样,那么只需定义一个<<
。
同样地,对于隐式转换似乎是一般解决方案的其他情况:只需定义适合该特定情况的内容,并避免引入一般的隐式转换。
要提供对内置类型的隐式转换,同时避免内置运算符的“全部免费”,您可以使用模板化类型转换,例如像这样:
operator<<
具有讽刺意味的是,#include <iostream>
template< class A, class B > struct Is_t_;
template< class Type > struct Is_t_<Type, Type> { using T = void; };
template< class A, class B >
using If_is_ = typename Is_t_<A, B>::T;
struct Bad_string
{
operator const char* () const { return "666!"; }
Bad_string( char const* = 0 ) {}
};
auto operator==( Bad_string const&, Bad_string const& )
-> bool
{ return true; }
struct Good_string
{
template< class Type, class Enabled_ = If_is_<const char*, Type>>
operator Type() const { return "42 :)"; }
Good_string( char const* = 0 ) {}
};
auto operator==( Good_string const&, Good_string const& )
-> bool
{ return true; }
#if defined( DO_GOOD )
using String = Good_string;
#elif defined( DO_BAD )
using String = Bad_string;
#else
# error "Define either DO_GOOD or DO_BAD, please."
#endif
auto main() -> int
{
String a, b;
(void) (a == "alfalfa"); // Errs for Bad_string
(void) (a + 1); // Compiles for Bad_string.
}
定义了此代码crashes the Visual C++ 2015 update 1 compiler,即所谓的“ICE”(内部编译器错误)。
该编译器的解决方法是将DO_GOOD
定义为
If_is_
答案 2 :(得分:1)
要将您的课程转换为int
,请执行
operator int() const
{
return m_int;
}