4

我创建了一个类 Chromosome,它最终只是一个带有 ostream 运算符的向量包装器,所以我决定改为 typedef 向量。但是,我在使用模板化 ostream 运算符时遇到了问题……这是最好的方法吗?(我已经看到了一些方法,但都没有得到任何工作)

template<typename G>
class Chromosome {
 public:
  typedef typename std::vector<G> type;
  typedef typename std::pair<type *,type *> ptr_pair;
};

template<typename G> //line 19 below:
std::ostream& operator<<(std::ostream& os, const Chromosome<G>::type& chromosome) {
  for(auto iter = chromosome.begin(); iter != chromosome.end(); ++iter)
    std::cout << *iter;
  return os;
}

目前我得到的错误是:

chromosome.h:19: error: expected unqualified-id before ‘&amp;’ token
chromosome.h:19: error: expected ‘)’ before ‘&amp;’ token
chromosome.h:19: error: expected initializer before ‘&amp;’ token

干杯。

4

2 回答 2

7

不幸的是,没有干净的方法可以做到这一点,因为编译器无法G从函数声明中推断出的类型

template<typename G>
std::ostream& operator<<(std::ostream& os, const typename Chromosome<G>::type& chromosome);

原因是,如果您要专门Chromosome针对不同的类型,最终可能会遇到编译器无法明确推断的情况G。例如:

template <typename G> class Chromosome {
public:
    typedef std::vector<G> type; // No typename needed here, BTW
};

template <> class Chromosome<int> {
public:
    typedef std::vector<double> type;
};

现在,如果你这样做会发生什么?

vector<double> v;
cout << v << endl;

在这种情况下,编译器无法判断Gis doubleor int,因为两者Chromosome<int>Chromosome<double>havevector<double>作为它们的嵌套类型。

要解决此问题,您必须显式使用类型vector<G>作为参数:

template<typename G>
std::ostream& operator<<(std::ostream& os, const std::vector<G>& chromosome);

不幸的是,确实没有更好的方法来做到这一点。这并不是语言中的真正缺陷,因为有充分的理由禁止它,但它确实阻止了你在这种情况下做你想做的事。

于 2011-02-12T01:47:37.357 回答
1

成员 typedeftype是一个依赖名称:它的含义取决于模板参数G。您需要使用 atypename告诉编译器type命名类型:

const typename Chromosome<G>::type&

有关完整说明,请考虑阅读 Stack Overflow C++ 常见问题解答文章Where to put the “template” and “typename” ondependent names

正如@templatetypedef 在评论中所暗示的那样,虽然这将使代码能够编译,但它不会“工作”允许您将 an 插入std::vector<G>到 an中,std::ostream因为type它位于非推导上下文中。

声明重载并获得预期行为的最简单方法是std::vector<G>直接用作参数类型:

template<typename G>
std::ostream& operator<<(std::ostream& os, const std::vector<G>& chromosome)
于 2011-02-12T01:36:50.053 回答