转换运算符在C ++中如何工作? [英] How do conversion operators work in C++?

查看:108
本文介绍了转换运算符在C ++中如何工作?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

考虑这个简单的例子:

template <class Type>
class smartref {
public:
    smartref() : data(new Type) { }
    operator Type&(){ return *data; }
private:
    Type* data;
};

class person {
public:
    void think() { std::cout << "I am thinking"; }
};

int main() {
    smartref<person> p;
    p.think(); // why does not the compiler try substituting Type&?
}

转换运算符在C ++中如何工作? (即)编译器何时尝试替换在转换运算符之后定义的类型

How do conversion operators work in C++? (i.e) when does the compiler try substituting the type defined after the conversion operator?

推荐答案

而不是使用跟随。

首先,请注意,转换函数从不用于转换为相同的类类型或基类类型。

First, note that conversion functions are never used to convert to the same class type or to a base class type.

参数传递期间的转换将使用复制初始化的规则。这些规则只考虑任何转换函数,不考虑是否转换为引用。

Conversion during argument passing will use the rules for copy initialization. These rules just consider any conversion function, disregarding of whether converting to a reference or not.

struct B { };
struct A {
  operator B() { return B(); }
};
void f(B);
int main() { f(A()); } // called!

参数传递只是复制初始化的一个上下文。另一种是使用复制初始化语法的纯形式

Argument passing is just one context of copy initialization. Another is the "pure" form using the copy initialization syntax

B b = A(); // called!



转换为参考



运算符,如果转换为的类型是一个左值,则可以转换为引用类型。

Conversion to reference

In the conditional operator, conversion to a reference type is possible, if the type converted to is an lvalue.

struct B { };
struct A {
  operator B&() { static B b; return b; }
};

int main() { B b; 0 ? b : A(); } // called!

另一个引用转换是直接绑定引用

Another conversion to reference is when you bind a reference, directly

struct B { };
struct A { 
  operator B&() { static B b; return b; }
};

B &b = A(); // called!



转换为函数指针



具有到函数指针或引用的转换函数,并且当进行调用时,可以使用它。

Conversion to function pointers

You may have a conversion function to a function pointer or reference, and when a call is made, then it might be used.

typedef void (*fPtr)(int);

void foo(int a);
struct test {
  operator fPtr() { return foo; }
};

int main() {
  test t; t(10); // called!
}

这个东西实际上可能变得非常有用。

This thing can actually become quite useful sometimes.

始终和无处不在的隐式转换也可以使用用户定义的转换。您可以定义一个返回布尔值的转换函数

The implicit conversions that happen always and everywhere can use user defined conversions too. You may define a conversion function that returns a boolean value

struct test {
  operator bool() { return true; }
};

int main() {
  test t;
  if(t) { ... }
}

在此情况下,通过 safe-bool idiom 可以使安全性更加安全,禁止转换为其他整数类型。 )转换在内置运算符期望某种类型的任何地方触发。但转换可能会阻碍。

(The conversion to bool in this case can be made safer by the safe-bool idiom, to forbid conversions to other integer types.) The conversions are triggered anywhere where a built-in operator expects a certain type. Conversions may get into the way, though.

struct test {
  void operator[](unsigned int) { }
  operator char *() { static char c; return &c; }
};

int main() {
  test t; t[0]; // ambiguous
}

// (t).operator[] (unsigned int) : member
// operator[](T *, std::ptrdiff_t) : built-in

调用可能不明确,因为对于成员,第二个参数需要转换,对于内置运算符,第一个需要用户定义的转换。其他两个参数分别匹配。在某些情况下,调用可以是非歧义的( ptrdiff_t 需要不同于 int )。

The call can be ambiguous, because for the member, the second parameter needs a conversion, and for the built-in operator, the first needs a user defined conversion. The other two parameters match perfectly respectively. The call can be non-ambiguous in some cases (ptrdiff_t needs be different from int then).

模板允许一些好东西,但最好对它们非常谨慎。以下使一个类型可以转换为任何指针类型(成员指针不被视为指针类型)。

Templates allow some nice things, but better be very cautious about them. The following makes a type convertible to any pointer type (member pointers aren't seen as "pointer types").

struct test {
  template<typename T>
  operator T*() { return 0; }
};

void *pv = test();
bool *pb = test();

这篇关于转换运算符在C ++中如何工作?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆