即使它是变量也不会被声明

时间:2014-11-11 20:57:21

标签: c++ variable-declaration

模板友元运算符重载中的变量声明有一些(简单看?)问题。 编译器给我一条消息:

main.cpp | 103 |错误:未在此范围|

中声明'ptemp'

代码:

template <typename K, typename I>
class Sequence
    {
    private:
         struct Data
         {
            K key;
            I data;
            Data *pnext;
          };

     Data *pHead;
    public:
    //(...)
    friend ostream &operator << <I,K> (ostream&, const Sequence<I,K>&);
    };



    template <typename I, typename K>
    ostream &operator << (ostream& stream, const Sequence<I,K> &cop)
    {
     Sequence<I,K>::Data *ptemp (cop.pHead); ///here is the error (?)

        stream << "-------------- PRINT BEGINS ---------------" << endl;
        if (!ptemp) //there is no elements
        {
        stream << "The list is empty, there is nothing to print!" << endl;
        stream << "--------------  PRINT ENDS  ---------------" << endl << endl;
        return stream;
        };
    }

编译器在发出声明时给出了没有声明“ptemp”的消息。当我擦除ptemp的初始化时也是如此。 我不明白这个宣言有什么不妥。我会很感激任何建议。

3 个答案:

答案 0 :(得分:3)

尝试以下

typename Sequence<I,K>::Data *ptemp (cop.pHead); 

答案 1 :(得分:2)

问题似乎是Sequence<I,K>::Data是一个依赖名称,编译器需要typename关键字的帮助才能知道该怎么做。所以你需要说typename Sequence<I,K>::Data *ptemp(cop.pHead);。我无法弄清楚 它如何在没有关键字的情况下解释它(我的第一个猜测,因为函数声明通过最烦恼的解析看起来并不正确在初始化中更改为a =没有修复它。)

另外,似乎您的内联friend声明可能是特定于编译器的扩展,应该可以避免。我不得不对你的代码进行多次更改,以便用g ++ 4.5重现问题中的错误。

答案 2 :(得分:0)

名称Sequence<I,K>::Data 取决于 IK的定义:编译器无法知道Data是一种类型还是模板实例Sequence<I,K>中的非类型(即值)。所以你需要通过在关键字typename前加上来告诉编译器它是一个类型,否则它假设它是一个非类型,所以这行被解析为两个值的乘法,其中第二个是'知道。有关详细说明,请参阅"Where and why do I have to put the “template” and “typename” keywords?"

typename Sequence<I,K>::Data *ptemp (cop.pHead);

如果您可以使用C ++ 11,则可以将完整类型替换为auto

auto ptemp = cop.pHead;

此外,您可以将朋友非会员定义直接放在班级中(使其成为会员!)。然后,您可以仅使用Sequence<I,K>引用Sequence,将Data简称为Data

public:
    friend ostream &operator << (ostream& stream, const Sequence &cop)
    {
        Data *ptemp (cop.pHead);
        ...
    }