gpt4 book ai didi

c++ - 复杂的C++模板代码

转载 作者:行者123 更新时间:2023-11-30 03:34:47 25 4
gpt4 key购买 nike

我一直在为 opencascade 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);
}

编译错误如下:

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> &)'

谁能指出我正确的方向?

最佳答案

提供的示例中存在多个错误。

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

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

其次,您正试图从 handle<Foo> 向下转换至 handle<Foo>这是一个毫无意义的操作。 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);
}

最后一点,那些 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);
}

关于c++ - 复杂的C++模板代码,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41765005/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com