C++中隠タイプ変換学習ノート


1 operator暗黙的なタイプの変換
1.1 std:refソースの中でreference_wrapper暗黙タイプ変換
std:refの実装には次のようなコードがあります。

template<typename _Tp>
 class reference_wrapper
 : public _Reference_wrapper_base<typename remove_cv<_Tp>::type>
 {
  _Tp* _M_data;

 public:
  typedef _Tp type;

  reference_wrapper(_Tp& __indata) noexcept
  : _M_data(std::__addressof(__indata))
  { }

  reference_wrapper(_Tp&&) = delete;

  reference_wrapper(const reference_wrapper&) = default;

  reference_wrapper&
  operator=(const reference_wrapper&) = default;
  //operator       
  operator _Tp&() const noexcept
  { return this->get(); }

  _Tp&
  get() const noexcept
  { return *_M_data; }

  template<typename... _Args>
 typename result_of<_Tp&(_Args&&...)>::type
 operator()(_Args&&... __args) const
 {
  return __invoke(get(), std::forward<_Args>(__args)...);
 }
 };
注意operator操作子を見てください。

operator _Tp&() const noexcept
  { return this->get(); }
は、タイプ変換に使用されます。
1.2簡単な例-一つのクラスをintに変更する例を実現する

#include <iostream>
/*
 *
 * c++ operator       
 *   std::ref   
 */ 
void f(int a)
{
 std::cout << "a = " << a << std::endl;
}
class A{
 public:
 A(int a):num(a){}
 ~A() {}

 operator int()
 {
  return num;
 }
 int num;
};

int main()
{
 A a(1);
 std::cout << a + 1 << std::endl;
 f(a);
 return 0;
}
もちろん、operatorによって暗黙的なタイプの転換が実現されるほか、c+++においても構造関数によって実現される。
2コンストラクタは、暗黙的なタイプの変換を実現します。
c+primerの本の中で言及します。
単一の実参照で呼び出すことができるコンストラクタは、フォームタイプからクラスタイプへの変換を定義しています。
次の例を見ます

#include <iostream>
/*
 *
 * c++          
 *   std::ref   
 */
class B{
 public:
 B(int a):num(a){}
 ~B() {}

 int num;
};

class A{
 public:
 A(int a):num(a){}
 A(B b):num(b.num){}
 ~A() {}

 int fun(A a)
 {
  std::cout << num + a.num << std::endl;
 }

 int num;
};

int main()
{
 B b(1);
 A a(2);
 //               
 a.fun(b); //     3
 return 0;
}
特に注意が必要なのは単一の参謀であり、構造関数は陰的な変換があり、条件が満たされないとだめです。
3 explicitキーワードを使用して、構造関数の陰的転換を避ける。
いくつかの場合、私たちは暗黙的な転換を望んでいません。望まない暗黙的な変換は意外な結果をもたらすかもしれません。explicitキーワードは、このような暗黙的な変換を禁止できます。上記のclass Aの構造関数を以下のように変更します。

class A{
 public:
 A(int a):num(a){}
 explicit A(B b):num(b.num){}
 ~A() {}

 int fun(A a)
 {
  std::cout << num + a.num << std::endl;
 }

 int num;
};
再度プログラムを実行してヒントがあります。
op 2.cpp:In function‘int main()':
op 2.cpp:29:error:no matching function for call to'A:fun(B)'
a.fun(b)
^
op 2.cpp:16:9:note:candidate:int A:fun(A)
int fun(A a)
^~
op 2.cpp:16:9:note:no known conversion for argment 1 from'B'to'A'
この時呼び出し方式を変更しました。

int main()
{
 B b(1);
 A a(2);
 a.fun(A(b));
 return 0;
}
C++言語の博大さと深さに感嘆するしかないです。この文章はまだ暗黙的な転換の入門レベルの総括にすぎません。
参考:
『C++Primer』隠蔽タイプ変換学習整理
以上はC++中隠しタイプの変換学習ノートの詳細です。C++中隠しタイプの変換に関する資料は他の関連記事に注目してください。