声明依赖于模板函数中未知类型的变量

rem*_*rem 4 c++ templates typeof visual-c++

假设我正在编写一个具有类型参数T的模板函数foo.它得到一个类型为T的对象,它必须有方法bar().在foo里面我想创建一个由bar返回的对象类型的向量.

在GNU C++中,我可以编写类似的东西:

template<typename T>
void foo(T x) {
    std::vector<__typeof(x.bar())> v;
    v.push_back(x.bar());
    v.push_back(x.bar());
    v.push_back(x.bar());
    std::cout << v.size() << std::endl;
}
Run Code Online (Sandbox Code Playgroud)

如何在Microsoft Visual C++中做同样的事情?有没有办法编写适用于GNU C++和Visual C++的代码?

Joh*_*itb 13

你可以用标准的c ++做到这一点

template<typename T>
struct id { typedef T type; };

template<typename T>
id<T> make_id(T) { return id<T>(); }

struct any_type {
  template<typename T>
  operator id<T>() const { return id<T>(); }
};

template<typename T, typename U>
void doit(id<T>, U& x) {
  std::vector<T> v;
  v.push_back(x.bar());
  v.push_back(x.bar());
  v.push_back(x.bar());
  std::cout << v.size() << std::endl;
}

template<typename T>
void foo(T x) {
    doit(true ? any_type() : make_id(x.bar()), x);
}
Run Code Online (Sandbox Code Playgroud)

有关解释,请参阅有条件的爱.


Ash*_*ain 7

C++ 0x提供decltype关键字作为标准的一部分,它解决了你的问题,如下所示:

template<typename T>
void foo(T x) {
    std::vector<decltype(x.bar())> v;
    v.push_back(x.bar());
    v.push_back(x.bar());
    v.push_back(x.bar());
    std::cout << v.size() << std::endl;
}
Run Code Online (Sandbox Code Playgroud)

Visual Studio 2010也支持这一点,GCC 4.3+和Comeau 4.3.9+也是如此(感谢Patrick).

  • 如果bar可能返回引用,则必须使用`typename remove_reference <decltype(x.bar())> :: type` (2认同)