复杂的C++;模板代码 我一直在为OpenCaseC++ C++编写一个C语言包。 我的C++有点生疏了,因为我过去几年主要和C语言合作过。

复杂的C++;模板代码 我一直在为OpenCaseC++ C++编写一个C语言包。 我的C++有点生疏了,因为我过去几年主要和C语言合作过。,c++,templates,C++,Templates,现在,我遇到了以下问题,无法找到解决方法: #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> {}; //! Expli

现在,我遇到了以下问题,无法找到解决方法:

#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);
}
#包括
//! 如果类T1是T2的基但不相同,则产生true的性状
模板
struct是_base_,但_不相同:std::是{}的_base_;
//! 显式专业化是特质解决问题的基础
//! 当T1和T2相同时,类型要求完整。
模板
结构是_base_,但_不相同:std::false_type{};
模板
类句柄
{
公众:
//!从手柄向下转换为基础类型的操作员
模板
静态类型名称std::enable_if::type
向下广播(常量句柄和对象)
{
返回句柄(动态强制转换(const强制转换(theObject.get()));
}
//!从指针到基类型的向下转换运算符
模板
静态类型名称std::enable_if::type
下行(常数T2*tpr)
{
返回句柄(动态强制转换(常量强制转换(thePtr));
}
};
福班
{
};
typedef handle\u Foo;
Handle\u Foo DownCastFoo(Handle\u Foo const&T){
返回句柄_Foo::向下转换(T);
}
编译器错误如下所示:

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> &)'
错误C2672'handle::DownCast':未找到匹配的重载函数
严重性代码说明项目文件行抑制状态
错误C2784“std::enable_if::type handle::DownCast(const T2*)”:无法从“const handle_Foo”推断“const T2*”的模板参数
严重性代码说明项目文件行抑制状态
错误C2893未能专门化函数模板“std::enable_if::type handle::DownCast(const handle&)”

有人能给我指出正确的方向吗?

提供的示例中有多个错误

首先,该示例暗示了
handle
类的
T*
构造函数和
get()
方法。将这些添加到
句柄
类:

explicit handle(T*);
const T* get() const;
其次,您试图从
handle
向下转换为
handle
,这是一个毫无意义的操作
Foo
甚至不是多态的。您的向下转换方法似乎是专门为不提供这种重载而设计的,因此您会得到错误。将
Foo
定义为多态,并添加派生类
Bar

struct Foo { virtual ~Foo() = default; };
struct Bar : public Foo {};
最后,将
DownCastFoo
更改为尝试向下转换到
Bar
,而不是
Foo
,错误得到解决

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

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

编辑:如果仅用于避免非法重载,则看起来像是启用。如果您使用
static\u assert
,您将得到更好的编译器错误

使用
static\u 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)));
    }
};

您好,我想这些代码定义现在已经完成了,如果我错过了smth,请告诉我。您发布的代码至少包含一个拼写错误(我希望如此)。创建您的应用程序。然后编译它。准确地获取要修复的错误。如果出现其他错误,请修复mcve。不要用手抄写。复制代码(通过复制粘贴)、用空格格式化、复制错误(通过复制粘贴)、用空格格式化。不要总结错误,包括所有警告和错误行。让别人知道什么是打字错误,什么是你真正的错误是不可接受的,不好,不坏,通常也不好。如果你的例子太长,那就尽量精简。第三次是他们说的魅力;)<代码>返回句柄(动态强制转换(const强制转换(theObject.get()))似乎暗示
handle
有一个
const T*get()const
方法,并且接受
T*
模板结构的构造函数是\u base\u,但不相同::std::false\u type{}
稍微简单一些。(您可以从基本模板中删除
Dummy
类型)谢谢,这更有意义。你知道,要尝试并减少别人6年前编写的代码并不总是那么容易的。用一种我甚至不编码的语言。我试图在以后发布问题时更加精确。非常感谢你的回答!我给了你一张追加投票(似乎没有公开记录,因为新成员至少需要15张追加投票才能做出任何决定)。
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)));
    }
};
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);
}