[英]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.