C++:如何确定变量是引用还是指针

5

我在代码的catch部分有一个宏,比如说

#define CATCH( doSomething )           \
    catch (MyException& e)             \
    {                                  \
        try                            \
        {                              \
            doSomething;               \
        }                              \
    }                                  \
    catch (MyException* e)             \
    {                                  \
        try                            \
        {                              \
            doSomething;               \
        }                              \
    }                         

doSomething部分中,我需要获取异常的内容,有办法可以做到吗?是否有一种类似这样使用的函数isPointer

try
{
    THROW(new MyException());
}
CATCH(                                 \
    if( isPointer(e) )                 \
    {                                  \
        std::cout << (*e).toString();  \
    }                                  \
    else                               \
    {                                  \
        std::cout << e.toString();     \
    }                                  \
)

3
你可以使用模板分发来实现这一点。 - Daniel
4
长时间盯着反斜杠的线条看会产生奇怪的视错觉……无论如何,你最好确保始终通过堆栈分配一个值并通过引用捕获它。在这里使用 new 没有任何好处;通过引用捕获允许您获得多态行为。 - Karl Knechtel
在C++11中,您可以使用类型特征来检查这一点。请参阅http://en.cppreference.com/w/cpp/types。另外,请记住,在捕获指针时,要记得使用`delete`! - Some programmer dude
1
@JoachimPileborg:不幸的是,在捕获指针时,无法知道是否应该删除它;一个疯子可能会throw new MyException,而另一个人可能会throw &static_exception。首先,您真的不应该抛出指针。 - Mike Seymour
当然,在CATCH宏中有“delete”,只是我太懒了,没写下所有东西。 - sukhmel
1个回答

11

只需使用重载以可能取消引用参数:

template<class T>
T& deref(T* p) { return *p; }

template<class T>
T& deref(T& r) { return r; }

并使用它:

CATCH(                                 \
    std::cout << deref(e).toString();  \
)

虽然我必须承认,我看不出动态分配异常对象的理由。


2
没有理由动态分配异常对象。 - Blazes
为什么要使用那些“\”?即使你不使用它们,C++也会跳过代码中的空格 :) - Mr.Anubis
@Mr.Anubis:那些是原始宏的一部分。 - Xeo
1
我也会为“没有动态分配的理由”点赞 =) 而且这种方式在这种情况下确实很管用,谢谢。 - sukhmel

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接