未能在试图code智能施法模板函数 [英] Failing in trying to code smart cast template function

查看:110
本文介绍了未能在试图code智能施法模板函数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我目前正在为codeA功能来执行的static_cast 或者基于其输入和输出的dynamic_cast 类型 DRY原则。对此我试图完成的功能如下:

I am currently trying to code a function to perform static_cast or dynamic_cast based on its input and output types in following of DRY principle. The function which i am trying to accomplish is as below:

#define where                       typename = typename
#define can_cast(FROM, TO)          std::is_convertible<FROM, TO>::value
#define can_dynamic_cast(FROM, TO) \
                                    can_cast(FROM, TO) && \
                                    !std::is_same<FROM, TO>::value && \
                                    std::is_class<TO>::value && \
                                    !std::is_const<FROM>::value && \ 
                                    std::is_base_of<TO, FROM>::value
#define can_static_cast(FROM, TO)   can_cast(FROM, TO)

template<typename _Tout, typename _Tin, where
    std::enable_if<
        !std::is_pointer<_Tout>::value &&
        !std::is_pointer<_Tin>::value &&
        can_cast_ptr(_Tin, _Tout)>::type>
inline _Tout* gc_ptr_cast(_Tin* const p) {
    if(can_dynamic_cast(_Tin*, _Tout*))
        return dynamic_cast<_Tout*>(p);
    if(can_dynamic_cast(_Tin*, _Tout*))
        return static_cast<_Tout*>(p);
    throw bad_cast();
}

但对于例如 gc_ptr_cast&LT将无法正常工作; INT&GT;(新INT(1))由于编译器的抱怨使得:

But it won't work for for example gc_ptr_cast<int>(new int(1)) due to the complaining of compiler such that:

[..] 错误:不能dynamic_cast的'P'(类型'诠释*常量')键入'诠释*'(目标不是指针或引用类)
               回报的dynamic_cast&LT; _Tout *&GT;(P)«;

[..] error: cannot dynamic_cast 'p' (of type 'int* const') to type 'int*' (target is not pointer or reference to class) return dynamic_cast<_Tout*>(p)«;

编译器应该处理的static_cast 而不是的dynamic_cast

现在我什至不知道如果我在正确的路径中使用&LT; type_traits方式&gt; 这样的目的

The compiler should process static_cast instead of dynamic_cast!
Now i am not even sure if i am in correct path using <type_traits> for such purpose.

我有一半的模板函数千与他们中的一些我需要执行的static_cast ,并在其中一些我需要的dynamic_cast ,并在剩下的一半我需要检查两者。在的dynamic_cast 是我的情况很重要,因为它是成功的在下面的例子中是一个重要组成部分,以做出正确的事情!

I have a half a thousand of template functions with in some of them i need to perform static_cast and in some of them i need to dynamic_cast and in half of the remaining i need to check both. The dynamic_cast are important in my case since it is successful in below example which is a crucial part to make things right!

struct base1 {};
struct base2 {};
struct derived : public base1, public base2 {};
.
.
.
derived obj;
base1* p1 = &obj;
base2* p2 = &obj;
assert(dynamic_cast<void*>(p1) == dynamic_cast<void*>(p2));  // will succeed 
assert(static_cast<void*>(p1) == static_cast<void*>(p2));    // will fail [ THIS IS WHY I CANNOT USE `static_cast` IN SOME CASES ]

我知道有href=\"http://www.boost.org/doc/libs/1_58_0_b1/boost/serialization/smart_cast.hpp\" rel=\"nofollow\">智能施法一个

I know there is a smart cast of boost library, but i want my code just depend on C++11 std. library.

1)我究竟做错了什么?

2)如何实现 gc_ptr_cast&LT;&GT;?()

1) What am i doing wrong?
2) How do i accomplish gc_ptr_cast<>()?

P.S:也许我​​在做了一些条件,我已经把 can_dynamic_cast ,但它的确定现在

P.S: Maybe i over did the some conditions, I have put in can_dynamic_cast but it's OK for now.

推荐答案

您尝试使用编译时的运行条件的条件。它基本上是坏主意。

You are trying to use compile-time conditions in runtime-conditions. It's basically bad idea.

inline _Tout* gc_ptr_cast(_Tin* const p) {
    if(can_dynamic_cast(_Tin*, _Tout*))
        return dynamic_cast<_Tout*>(p);
    if(can_dynamic_cast(_Tin*, _Tout*))
        return static_cast<_Tout*>(p);
    throw bad_cast();
}

这应该在编译时检查,方面因为 can_dynamic_cast 被改写为编译时检查你的情况。

This should be rewritten in terms of compile-time checks, since can_dynamic_cast is compile-time check in your case.

我觉得像这样可以帮助你:

I think something like this can help you:

template<typename _Tout, typename _Tin>
inline _Tout* ptr_cast(_Tin* const p,
typename std::enable_if<can_dynamic_cast(_Tin*, _Tout*)>::type* = 0)
{
   return dynamic_cast<_Tout*>(p);
}

template<typename _Tout, typename _Tin>
inline _Tout* ptr_cast(_Tin* const p,
typename std::enable_if<can_static_cast(_Tin*, _Tout*)>::type* = 0)
{
   return static_cast<_Tout*>(p);
}

template<typename _Tout, typename _Tin>
inline _Tout* ptr_cast(_Tin* const p,
typename std::enable_if<!can_static_cast(_Tin*, _Tout*) &&
!can_dynamic_cast(_Tin*, _Tout*)>::type* = 0)
{
   throw std::bad_cast();
}

template<typename _Tout, typename _Tin, where
    std::enable_if<
        !std::is_pointer<_Tout>::value &&
        !std::is_pointer<_Tin>::value &&
        can_cast(_Tin, _Tout)>::type>
inline _Tout* gc_ptr_cast(_Tin* const p) {
    return ptr_cast<_Tout>(p);
}

这篇关于未能在试图code智能施法模板函数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆