C++ 使用模板化参数的 value_type

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/8073052/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-28 17:58:17  来源:igfitidea点击:

Using a templated parameter's value_type

c++templatesstd

提问by Jonathan Winks

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

应该如何使用 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();
}

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?

我以为这是 ::value_type 的用途?

回答by celtschk

You have to use typename:

你必须使用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 * pmay 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 typenameis considered a variable.

原因是编译器无法知道 T::value_type 是否是成员变量的类型(没有人会阻止您定义类型struct X { int value_type; };并将其传递给模板)。但是,如果没有该函数,则无法解析代码(因为构造的含义会根据某些标识符是指定类型还是变量而变化,例如T * p可能是乘法或指针声明)。因此,规则是所有可能是类型或变量并且没有通过前缀将其显式标记为类型的东西都typename被视为变量。

回答by Mark Ransom

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

使用typename关键字表示它确实是一种类型。

void push(typename T::value_type& item)

typename T::value_type pop()

回答by Neil McGill

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