簡體   English   中英

隱式轉換為C ++模板對象

[英]Implicit conversion to a C++ template object

我有一個A類:

template <typename T, int I> struct A {};

和B類。我希望類型B的對象在作為函數參數給出時隱式轉換為A. B看起來像這樣:

template <typename T>
struct B {
  operator A<T,0> &() const { return *new A<T,0>(); }
};

但是,我的測試(下面)失敗了GCC 4.5,給出錯誤: 沒有匹配函數來調用'test(B&)'我在哪里錯了? 其他編譯器也拒絕這個嗎?

template <typename T, int I>
void test(A<T,I> &a) { delete &a; }

int main(int argc, char *argv[])
{
  B<int> b;
  test(b);
  return 0;
}

ps我現在把自己的解決方案放在下面的答案中。

與您的問題無關但return *new A<T,0>(); 這是錯的 泄漏記憶 引發內存泄漏。 應該使用new位置。 return A<T, 0>(); 並從返回類型中刪除引用工作正常,並不會泄漏內存。

如果您想要從B到A的隱式轉換,您需要:

B上的演員:

operator A<T,0>();

或者是一個采用B引用的構造函數:

A( const B& other );

或者B來自A.你宣稱:

operator A<T,0> &() const;

看起來有點像一個錯誤聲明的重載地址。

但是,由於test()接受引用(並且非const),因此轉換操作符選項將不起作用。

這是我測試過的:

template <typename T, int I> struct A {};

template <typename T>
struct B {
  //operator A<T,0> &() const { return *new A<T,0>(); }

    template< int I >
    operator A<T, I> () const { return A< T, 0 >(); }
};

template <typename T, int I>
void test(A<T,I> &) { }

int f()
{
  B<int> b;

  A<int, 0> a( b );
  test(a); // <-- Success

  test(b); // <-- Failure, "could not deduce template argument"
  return 0;
}

通過初始化局部變量轉換為A工作正常。

你確定你真的想要這樣的隱式轉換嗎? 這聽起來像是混淆自己或其他維護者的完美方式,或者更糟糕的是,使用錯誤的參數調用函數,因為隱式轉換允許它。 相反,請考慮像std::make_pair這樣的make_A模板,以明確顯示您在呼叫站點的意圖。

提供如下所述的test過載將使得能夠在問題中編寫test(b)
例如:

template <typename T>
void test(B<T> const &b) {
  test( static_cast< A<T,0>& >( b ) );
}

test(b); // caller

如果不允許這樣的重載但你可以修改B的定義,那么如何提供返回A成員函數,而不是轉換函數?

template <typename T>
struct B {
  A<T,0> &to_A() const { return *new A<T,0>(); }
};

test( b.to_A() );

如果不允許修改B的定義,上面的to_A將是一個自由函數,如下所示而不是成員函數:

template <typename T>
A<T,0> &to_A(B<T> const &b) {
  return static_cast< A<T,0>& >( b );
}

test( to_A( b ) );

希望這可以幫助

這在VC ++中也失敗了。 要使其工作,請添加以下方法:

template <typename T>
void test(B<T> &b)
{
   test( static_cast< A<T,0>& > (b) );
}

這將采用實際的B ,明確地進行轉換(通過static_cast ),然后使用我們剛剛創建的A調用test

我運行時遇到錯誤。 我希望這只是示例代碼,而您在實際代碼中沒有delete &a RobH為您提供了更好的轉換運算符,並避免指針混亂。

我已經決定使用Konrad建議的pass by value轉換運算符; Let_Me_Be的顯式模板函數調用; 我在頂部撒了一點C ++ 0x魔法:一個關於要測試的參數的右值參考。 (或者,現在應該是C ++ 2011嗎?)

template <typename T, int I> struct A { int x; };

template <typename T>
struct B {
  operator A<T,0> () const { return A<T,0>(); }
};

template <typename T, int I>
void test(A<T,I> &&a) { a.x=7; printf("%d\n", x); }

int main(int argc, char *argv[])
{
  B<int> b;
  test<int,0>(b);
  return 0;
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM