使用模板化参数的value_type

Using a templated parameter's value_type

本文关键字:value type 参数      更新时间:2023-10-16

如何使用std容器的value_type?
我试着这样使用它:

#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();
}

但是结果是:

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’

我认为这是什么::value_type是为?

你必须使用typename:

typename T::value_type pop()

等等

原因是编译器无法知道T::value_type是否是成员变量的类型(没有人阻止您定义类型struct X { int value_type; };并将其传递给模板)。然而,如果没有这个函数,代码就无法被解析(因为构造的含义取决于某个标识符是否指定了类型或变量,例如T * p可能是乘法或指针声明)。因此,规则是,所有可能是类型或变量并且没有通过使用typename前缀显式标记为类型的内容都被认为是变量。

使用typename关键字来表明它确实是一个类型。

void push(typename T::value_type& item)
typename T::value_type pop()

以下是上述公认答案的完整实现,以防对任何人有所帮助。

#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;
}

为方便起见,一个相当常见的做法是提供一个代表底层值类型的别名。

template <typename T>
class TSContainer {
private:
    T container;
public:
    using value_type = typename T::value_type;
    void push(value_type& item)
    {
        container.push_back(item);
    }
    
    value_type pop()
    {
        value_type item = container.pop_front();
        return item;
    }
};
相关文章: