2017-01-20 5 views
0

私はopencascade C++のC#へのラッパーを開発しています。 私のC++は、ここ数年、主にC#で作業していたので少し錆びました。複雑なC++テンプレートコード

今、私は次のような問題が発生したことだし、それを修正する方法を見つけ出すことができませんでした:

#include <type_traits> 

//! Trait yielding true if class T1 is base of T2 but not the same 
template <class T1, class T2, class Dummy = void> 
struct is_base_but_not_same : std::is_base_of <T1, T2> {}; 

//! Explicit specialization of is_base_of trait to workaround the 
//! requirement of type to be complete when T1 and T2 are the same. 
template <class T1, class T2> 
struct is_base_but_not_same <T1, T2, typename std::enable_if <std::is_same <T1, T2>::value>::type> : std::false_type {}; 

template <class T> 
class handle 
{ 
public: 
    //! Down casting operator from handle to base type 
    template <class T2> 
    static typename std::enable_if<is_base_but_not_same<T2, T>::value, handle>::type 
     DownCast(const handle<T2>& theObject) 
    { 
     return handle(dynamic_cast<T*>(const_cast<T2*>(theObject.get()))); 
    } 

    //! Down casting operator from pointer to base type 
    template <class T2> 
    static typename std::enable_if<is_base_but_not_same<T2, T>::value, handle>::type 
     DownCast(const T2* thePtr) 
    { 
     return handle(dynamic_cast<T*>(const_cast<T2*>(thePtr))); 
    } 
}; 

class Foo 
{ 

}; 

typedef handle<Foo> Handle_Foo; 

Handle_Foo DownCastFoo(Handle_Foo const &T) { 
    return Handle_Foo::DownCast(T); 
} 

compilorエラーは次のとおりです。

Error C2672 'handle<Foo>::DownCast': no matching overloaded function found 
Severity Code Description Project File Line Suppression State 
Error C2784 'std::enable_if<is_base_but_not_same<T2,T,void>::value,handle<T>>::type handle<T>::DownCast(const T2 *)': could not deduce template argument for 'const T2 *' from 'const Handle_Foo' 
Severity Code Description Project File Line Suppression State 
Error C2893 Failed to specialize function template 'std::enable_if<is_base_but_not_same<T2,T,void>::value,handle<T>>::type handle<T>::DownCast(const handle<T2> &)' 

誰も私を指すことができます正しい方向に?

+0

こんにちは、私はこれらのコードの定義が完了していると思います。 –

+1

あなたが投稿したコードに少なくとも1つのタイプミスがあります。 [mcve]を作成します。それをコンパイルします。修正したいエラーを正確に取得します。別のエラーが発生した場合は、mcveを修正してください。手書きでは転載しないでください。コードを(コピー貼り付けで)コピーし、スペースでフォーマットし、(コピー貼り付けで)エラーをコピーし、スペースでフォーマットします。エラーを要約したり、すべての警告とエラー行を含めたりしないでください。誰かに誤字があり、実際のエラーは何かを理解するように頼むことは、受け入れられない、良い、悪くない、そして一般的に良くないことです。あなたの例が長すぎる場合は、最小限に抑えてください。 – Yakk

+0

第3回は彼らが言っている魅力です;) –

答えて

0

提供されている例に複数のエラーがあります。

まず、この例は、handleクラスの場合、T*コンストラクタとget()メソッドを意味します。 handleクラスにこれらを追加します。

explicit handle(T*); 
const T* get() const; 

第二には、あなたは無意味な操作ですhandle<Foo>からhandle<Foo>からダウンキャストしようとしています。 Fooは多型でもありません。あなたのダウンキャスト方法は、このオーバーロードを提供しないように特別に設計されているように見えます。 Fooをポリモーフィックに定義し、派生クラスBarを追加します。

struct Foo { virtual ~Foo() = default; }; 
struct Bar : public Foo {}; 

最後に、変更DownCastFooBar代わりのFooにダウンキャストしようとすると、エラーが解決されます。

最終的には、const_castは非常に疑わしく見えます。残念ながら、より良いアドバイスを提供するために十分な情報があなたの例にはありません。


全正しい例

#include <type_traits> 

//! Trait yielding true if class T1 is base of T2 but not the same 
template <class T1, class T2, class Dummy = void> 
struct is_base_but_not_same : std::is_base_of <T1, T2> {}; 

//! Explicit specialization of is_base_of trait to workaround the 
//! requirement of type to be complete when T1 and T2 are the same. 
template <class T1, class T2> 
struct is_base_but_not_same <T1, T2, typename std::enable_if <std::is_same <T1, T2>::value>::type> : std::false_type {}; 

template <class T> 
class handle 
{ 
public: 
    explicit handle(T*); 
    const T* get() const; 
public: 
    //! Down casting operator from handle to base type 
    template <class T2> 
    static typename std::enable_if<is_base_but_not_same<T2, T>::value, handle>::type 
     DownCast(const handle<T2>& theObject) 
    { 
     return handle(dynamic_cast<T*>(const_cast<T2*>(theObject.get()))); 
    } 

    //! Down casting operator from pointer to base type 
    template <class T2> 
    static typename std::enable_if<is_base_but_not_same<T2, T>::value, handle>::type 
     DownCast(const T2* thePtr) 
    { 
     return handle(dynamic_cast<T*>(const_cast<T2*>(thePtr))); 
    } 
}; 

struct Foo { virtual ~Foo() = default; }; 
struct Bar : public Foo {}; 

typedef handle<Foo> Handle_Foo; 
typedef handle<Bar> Handle_Bar; 

Handle_Bar DownCastFoo(Handle_Foo const &T) { 
    return Handle_Bar::DownCast(T); 
} 

編集:enable_ifのみ違法な過負荷を回避するために使用されているように見えます。代わりにstatic_assertを使用すると、より良いコンパイラエラーが発生します。 static_assertを使用して

例:

template <class T> 
class handle 
{ 
public: 
    explicit handle(T*); 
    const T* get() const; 
public: 
    //! Down casting operator from handle to base type 
    template <class T2> 
    static handle DownCast(const handle<T2>& theObject) 
    { 
     static_assert(std::is_same<T, T2>::value == false, 
      "Can't downcast from between identical types"); 
     static_assert(std::is_base_of<T2, T>::value, 
      "Can only down cast from a derived type to a base type"); 
     return handle(dynamic_cast<T*>(const_cast<T2*>(theObject.get()))); 
    } 

    //! Down casting operator from pointer to base type 
    template <class T2> 
    static handle DownCast(const T2* thePtr) 
    { 
     static_assert(std::is_same<T, T2>::value == false, 
      "Can't downcast from between identical types"); 
     static_assert(std::is_base_of<T2, T>::value, 
      "Can only down cast from a derived type to a base type"); 
     return handle(dynamic_cast<T*>(const_cast<T2*>(thePtr))); 
    } 
}; 

今、あなたのオリジナルのユースケースは、エラーメッセージ"Can't downcast from between identical types"を生成します。

struct Foo { virtual ~Foo() = default; }; 
struct Bar : public Foo {}; 

typedef handle<Foo> Handle_Foo; 

Handle_Foo DownCastFoo(Handle_Foo const &T) { 
    return Handle_Foo::DownCast(T); 
} 
+0

ありがとうございます。 6年前に他の誰かが作ったコードを解読して解読することは必ずしも容易ではないことは承知しています。ある言語では、私はコードしていません。私は問題を投稿するときに、より正確にしようとします。本当にあなたの答えをありがとう!私はあなたにupvoteを与えました(新しいメンバーは、少なくとも15枚のアップフォートが必要ですので、公開されていないようです)。 –