0

次のような関数テンプレートがあるとします。

template<class T>
inline
void
doStuff(T* arr)
{
  // stuff that needs to use sizeof(T)
}

次に、別の.hファイルに、次のテンプレート クラスFooがあります。

public: operator T*() const;

今、私はそれらが異なる T であることを理解しています。しかし、スタックに変数がある場合、それを任意の種類のポインターFoo<Bar> fに強制する唯一の方法は、を呼び出すことです。それでも、 call の場合、GCC は、 operator を自動的に使用して強制し、関数テンプレートをasで特殊化する代わりに、取ることができないと文句を言います。operator T*()doStuff(f)doStuffFoo<Bar>T*()Bar*BarT

これを 2 つのテンプレートで機能させるためにできることはありますか? または、テンプレート関数の引数が実際のポインター型である必要があるか、強制演算子を持つテンプレート クラスを非テンプレート関数に渡す必要がありますか?

4

5 に答える 5

3

GCCは正しいです。テンプレート引数では完全一致のみが考慮され、型変換は考慮されません。そうしないと、無限の (または少なくとも指数関数的な) 量のコンバージョンを考慮する必要があるためです。

実行する予定の他のテンプレートが Foo<T> だけである場合、最善の解決策は次を追加することです。

template<typename T> inline void doStuff(const Foo<T>& arr) {
    doStuff(static_cast<T*>(arr));
}

多くのテンプレートでこの問題が発生している場合は、次の方法で修正できます。

#include <boost/type_traits/is_convertible.hpp>
#include <boost/utility/enable_if.hpp>
template<template <typename> class T, typename U> inline typename boost::enable_if<typename boost::is_convertible<T<U>, U*>::type>::type doStuff(const T<U>& arr) {
    doStuff(static_cast<U*>(arr));
}

少し冗長ですが;-)

于 2008-10-12T21:39:03.867 に答える
2

これは試してみる価値があるかもしれません:

doStuff<Bar>(f);

これにより、コンパイラは T* が Bar* であることを期待し、Foo の演算子 T*() を使用してキャストを実行すると思いますが、試したとは言えません。

于 2008-10-12T21:40:16.860 に答える
0

おそらくレオンの考えが一番だろう。しかし、ピンチでは、キャスト演算子を明示的に呼び出すこともできます:

doStuff(static_cast<Bar*>(f));
于 2008-10-13T00:58:34.153 に答える
-1

変換が機能しない理由はわかりませんが、オーバーロードを使用して問題を解決できます


template 
inline
void 
doStuff(T& arrRef)
{
  doStuff(&arrRef);
}
于 2008-10-12T21:16:29.390 に答える
-1

T* は、あなたが考えている意味では T とは別の型ではありません。ポインターは型修飾子です。標準がそれについて何を言っているのかわかりませんが、変数はすでに T 型であるため、再度変換しようとはしません。ポインタを取得するためにカスタム処理を行いたい場合は、& 演算子をオーバーロードします。

于 2008-10-12T21:24:34.880 に答える