Using a templated parameter's value_type

2020-06-09 04:17发布

How is one supposed to use a std container's value_type?
I tried to use it like so:

#include <vector>

using namespace std;

template <typename T>
class TSContainer {
private:
        T container;
public:
        void push(T::value_type& item)
        {
                container.push_back(item);
        }
        T::value_type pop()
        {
                T::value_type item = container.pop_front();
                return item;
        }
};
int main()
{
        int i = 1;
        TSContainer<vector<int> > tsc;
        tsc.push(i);
        int v = tsc.pop();
}

But this results in:

prog.cpp:10: error: ‘T::value_type’ is not a type
prog.cpp:14: error: type ‘T’ is not derived from type ‘TSContainer<T>’
prog.cpp:14: error: expected ‘;’ before ‘pop’
prog.cpp:19: error: expected `;' before ‘}’ token
prog.cpp: In function ‘int main()’:
prog.cpp:25: error: ‘class TSContainer<std::vector<int, std::allocator<int> > >’ has no member named ‘pop’
prog.cpp:25: warning: unused variable ‘v’

I thought this was what ::value_type was for?

3条回答
淡お忘
2楼-- · 2020-06-09 04:36

Here is a full implementation of the accepted answers above, in case it helps anyone.

#include <iostream>
#include <list>

template <typename T>
class C1 {
  private:
    T container;
    typedef typename T::value_type CT;
  public:
    void push(CT& item) {
        container.push_back(item);
    }

    CT pop (void) {
        CT item = container.front();
        container.pop_front();
        return item;
    }
};

int main() {
    int i = 1;
    C1<std::list<int> > c;
    c.push(i);
    std::cout << c.pop() << std::endl;
}
查看更多
Emotional °昔
3楼-- · 2020-06-09 04:53

Use the typename keyword to indicate that it's really a type.

void push(typename T::value_type& item)

typename T::value_type pop()
查看更多
Evening l夕情丶
4楼-- · 2020-06-09 05:00

You have to use typename:

typename T::value_type pop()

and so on.

The reason is that the compiler cannot know whether T::value_type is a type of a member variable (nobody hinders you from defining a type struct X { int value_type; }; and pass that to the template). However without that function, the code could not be parsed (because the meaning of constructs changes depending on whether some identifier designates a type or a variable, e.g.T * p may be a multiplication or a pointer declaration). Therefore the rule is that everything which might be either type or variable and is not explicitly marked as type by prefixing it with typename is considered a variable.

查看更多
登录 后发表回答