如何使用decltype来获取引用的类型?

时间:2011-02-11 15:39:22

标签: c++ c++11 decltype c++builder-2010

我在CodeGear RAD Studio中使用decltype处理一些代码。我尝试过天真的解决方案,看起来与此不同:

int main(int, char**) {
    int i;
    int &ir = i;
    decltype((ir)) ir_clone = ir;
}

当然,这无法编译:内部编译器错误。我宁愿怀疑该代码没有什么特别的错误,并且存在关于引用表达式的编译器错误。 (顺便说一下,g ++对代码没有任何问题并且编译得很好。)然而,这无助于解决问题,因为该平台是不可协商的。

如果,上面,我写过

    decltype(ir) ir_clone = ir; /* No extra parens */

它编译并按预期工作。但是,问题并没有就此结束,因为这不能正确地计算环境中的常量。特别是:

struct S { int i; } s;
const S* p = &s;
decltype(p->i)   i0 = s.i; /* i0 is an int */
decltype((p->i)) i1 = s.i; /* i1 is a const int& */

如果我不使用parens使参数成为表达式,我就失去了我需要的参数的常量。

我可以使用的另一个工具是简单的模板,如下所示:

template<class T> struct unref     { typedef T type; }
template<class T> struct unref<T&> { typedef T type; }

这让我可以使用unref<int&>::type删除某个类型的引用部分。

我似乎无法弄清楚如何将所有这些工具放在一起以获得我需要的类型的成功表达。对于我需要的一件事,我正在研究一个“foreach”的广义宏。 (是的,我知道Boost做得更好。)它需要处理以下场景:

(vector<int>) vi          => vector<int>
(vector<int>&)vir         => vector<int>
(const vector<int>) cvi   => const vector<int>
(const vector<int>&)cvir  => const vector<int>
(const P*) cp->vi         => const vector<int>
(P*) p->vi                => vector<int>

到目前为止,我的简单尝试失败了:

unref<decltype(cp->vi)>   /* is vector<int>, not what I need. */
unref<decltype((cp->vi))> /* is const vector<int>, which is right. */

unref<decltype(vir)>      /* is vector<int>, which is right. */
unref<decltype((vir))>    /* Internal Compiler Error, which is a headache. */

让我走上正轨的任何想法?希望有一些我想念的简单事物。也许我是从错误的角度攻击这个问题。

2 个答案:

答案 0 :(得分:2)

尝试制作一个不同的,更复杂的表达式,以产生您想要的相同类型,例如:

decltype((void(), ir))

我无法告诉你它为什么修复它,但有时一个不同的表达式就可以解决问题。

答案 1 :(得分:2)

您可以使用std :: remove_reference(请参阅http://en.cppreference.com/w/cpp/types/remove_reference)。