为什么GCC无法使用声明将其解析为正确的类型 [英] why can't GCC resolve this using declaration to the correct type

查看:87
本文介绍了为什么GCC无法使用声明将其解析为正确的类型的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在我正在研究的项目中进行编码时,我发现了一些奇怪的东西:

While coding around in a project I'm working on, I discovered something really odd:

namespace detail {

    struct tuplelike_tag { };
    struct arraylike_tag { };

    template<typename>
    struct call_with_traits;

    template<typename... Ts>
    struct call_with_traits<std::tuple<Ts...>> {
        using tag = tuplelike_tag;

        enum { size = sizeof...(Ts) };
    };

    template<typename T, std::size_t Sz>
    struct call_with_traits<std::array<T, Sz>> {
        using tag = arraylike_tag;

        enum { size = Sz };
    };

    template<typename T, std::size_t Sz>
    struct call_with_traits<T[Sz]> {
        using tag = arraylike_tag;

        enum { size = Sz };
    };

    template<typename F, typename T, int... Is>
    auto call_with(F && f, T && tup, indices<Is...>, tuplelike_tag) -> ResultOf<Unqualified<F>> {
        return (std::forward<F>(f))(std::get<Is>(std::forward<T>(tup))...);
    }

    template<typename F, typename A, int... Is>
    auto call_with(F && f, A && arr, indices<Is...>, arraylike_tag) -> ResultOf<Unqualified<F>> {
        return (std::forward<F>(f))(std::forward<A>(arr)[Is]...);
    }
}

template<typename F, typename Cont>
inline auto call_with(F && f, Cont && cont) -> ResultOf<Unqualified<F>> {
    using unqualified = Unqualified<Cont>;
    using traits  = typename detail::call_with_traits<unqualified>;
    using tag     = typename detail::call_with_traits<unqualified>::tag;
    using no_tag  = typename traits::tag;   // this is what it's all about
    return detail::call_with(std::forward<F>(f), std::forward<Cont>(cont), build_indices<traits::size>(), tag());
}

此代码的奇怪之处在于 tag 解析为 typename detail :: call_with_traits :: tag; ,但出现 no_tag 错误:

The odd thing about this code is that tag gets resolved to typename detail::call_with_traits::tag;, but no_tag errors out:

error: no type named ‘tag’ in ‘using traits = struct detail::call_with_traits<typename std::remove_cv<typename std::remove_reference<_To>::type>::type>’

即使它应该在同一结构中引用相同的using声明。
我缺少什么,还是GCC中的某些错误?

even though it should refer to the same using declaration in the same struct. Is there something I'm missing, or is this some bug in GCC?

A 在线示例可以在此处找到,包括来自GCC的相关错误消息。

A live example can be found here, including the related error message from GCC.

推荐答案

这似乎是g ++ 4.7.2中的错误。这是一个最小的示例:

This appears to be a bug in g++ 4.7.2. Here is a minimal example:

template<typename> struct A { using tag = int; };

template<typename T>
inline void f() {
  using AT = A<T>;
  typename A<T>::tag x; // no error
  typename   AT::tag y; // error
}

int main(int argc, char ** argv) {
  f<int>();

  return 0;
}

如果 typedef 代替了 using 声明,或者如果您使用 A< int> 代替了 A< T>

There are no errors if a typedef is used instead of a using declaration, or if you use A<int> instead of A<T>.

这篇关于为什么GCC无法使用声明将其解析为正确的类型的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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