可变参数模板和“预期的类型”错误

时间:2012-04-27 20:33:42

标签: c++ c++11 variadic-templates

我正在(仅主要用于学习目的)自己实现tuple并且我刚刚遇到了问题。我有以下代码:

namespace Rose
{
    template<typename T>
    struct RemoveReference
    {
        typedef T Type;
    };

    template<typename T>
    struct RemoveReference<T &>
    {
        typedef T Type;
    };

    template<typename... Elems>
    class Tuple;

    template<typename First, typename... Elems>
    class Tuple<First, Elems...>
    {
    public:
        Tuple(First a, Elems... more)
            : More(more...), Element(a)
        {
        }

        Tuple<First, Elems...> & operator=(const Tuple<RemoveReference<First>::Type,
                                           RemoveReference<Elems>::Type...> & rhs)
        {
            this->Element = rhs.Element;
            this->More = rhs.More;

            return *this;
        }

    private:
        Tuple<Elems...> More;
        First Element;
    };

    template<typename Only>
    class Tuple<Only>
    {
    public:
        Tuple(Only a) : Element(a)
        {
        }

        Tuple<Only> & operator=(const Tuple<RemoveReference<Only>::Type> & rhs)
        {
            this->Element = rhs.Element;

            return *this;
        }

    private:
        Only Element;
    };
}

int main()
{
    Rose::Tuple<int, float, int> t(1, 1.f, 2);
}

导致跟随错误(有更多错误,但这一个是必不可少的):

  

错误:模板参数列表中参数1的类型/值不匹配'template struct Rose :: Tuple'   错误:期望一个类型,得到'Rose :: RemoveReference :: Type'

我真的不明白这是什么意思。 RemoveReference特征在单独使用时有效。

以下是两个测试用例:

我用G ++ 4.6.1,4.5.1和Clang ++ 2.9尝试过这段代码。

出现这些错误的原因是什么?

1 个答案:

答案 0 :(得分:5)

RemoveReference<T>::Type是从属类型,因此您需要在此处添加typename

        Tuple<First, Elems...> & operator=(const Tuple<typename RemoveReference<First>::Type,
                                                       typename RemoveReference<Elems>::Type...> & rhs)

可能还有其他地方。