0

我在文件中有一个带有内部类的以下模板map.hpp

template<typename Key_T, typename Mapped_T>
class Map {
    // public members of Map ...

    class Iterator {
        //public members of Iterator ...

        friend bool operator!=(const Iterator &i, const Iterator &j) {
            return (i.link != j.link);  
        }

        // private members of iterator ...
        Node * link;
    };
};
#include "map.hxx"   //implementation file for member methods is separate

main.cpp我调用以下内容时,到目前为止一切正常:

Map<int, int> x;
// bunch of insertions ...
for (auto it = x.begin; it != x.end(); ++it) {
    // Do something with it ...   
}

但是,我想将朋友函数移出map.hpp文件并移入map.hxx包含其他实现的文件中。

问:是否可以将免费功能移动到.hxx文件中?如何?

我厌倦了在 Iterator 类中将函数声明为朋友,并在实现文件中执行了以下操作:

template<typename Key_T, typename Mapped_T>
bool operator!=(const typename Map<Key_T, Mapped_T>::Iterator & i,
                const typename Map<Key_T, Mapped_T>::Iterator & j) {
    return (i.link != j.link);
}

但是它失败了:

$clang++ -std=c++11 -stdlib=libc++ -Wall -Wextra -g main.cpp 

Undefined symbols for architecture x86_64:
  "shiraz::operator!=(shiraz::Map<int, int>::Iterator const&, shiraz::Map<int, int>::Iterator const&)", referenced from:
      _main in main-3oCRAm.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)

谢谢!

4

1 回答 1

2

没有相应匹配的friend声明将向封闭的命名空间注入一个新函数。此功能只能通过 ADL 找到

做你想做的最简单的方法是在iterator类中留下一个存根实现,并将它转发给外部的“真实”函数。这保留了很好的 ADL-only 查找!=,这很容易解决一些棘手的重载问题。辅助函数可以简单地成为 atemplate<class Iterator>并且更正常地成为朋友,并且具有狭窄的实现,并且不能通过 ADL 找到,而是通过完全限定的查找来找到。或者它可能是封闭映射的静态成员函数。

template<typename Key_T, typename Mapped_T>
class Map {
  class Iterator;
  static bool it_equal( Iterator const&, Iterator const& );
  class Iterator {
    friend class Map;
    friend bool operator!=(const Iterator &i, const Iterator &j) {
      return !Map::it_equal(i,j);
    }
    friend bool operator==(const Iterator &i, const Iterator &j) {
      return Map::it_equal(i,j);
    }
    Node * link;
  };
};

现在你的.hxx简单工具bool Map<blah>::it_equal(blah)就完成了。

于 2015-03-18T00:22:04.223 回答