类模板交友功能模板

时间:2011-10-29 18:03:20

标签: c++ templates

当我尝试从以下代码创建可执行文件时出现链接器错误。我得到的印象是我需要放置一些“typename s”或做出一些前瞻性声明;我尝试过几种组合但没有效果。

template<typename T>
class enabled
{
  private:
    T type_;
    friend const T& typeof(const enabled<T>& obj); // Offending line
};

template<typename T>
const T& typeof(const enabled<T>& obj) {
    return obj.type_;
}


int main()
{
    enabled<std::string> en;
    std::cout << typeof(en);

    std::cin.clear(), std::cin.get();
    return 0;
}
  

1&gt; main.obj:错误LNK2001:未解析的外部符号“class std :: string const&amp; __cdecl typeof(启用类&lt;类std :: string&gt; const&amp;)”

2 个答案:

答案 0 :(得分:4)

通过前向声明并指定该函数是模板化的

template<typename T> class enabled;

template<typename T>
const T& typeof(const enabled<T>& obj) {
    return obj.type_;
}

template<typename T>
class enabled
{
  private:
    T type_;
    friend const T& typeof<>(const enabled<T>& obj);
};

答案 1 :(得分:3)

问题在于,作为类的朋友的函数不是函数模板,而实际定义的函数是函数模板。

您需要做的就是将朋友的功能模板设为:

template<typename T>
class enabled
{
  private:
    T type_;

    template<typename U> //<-------------------------------note this
    friend const U& typeof_(const enabled<U>& obj);  //use U 
};

现在编译得很好:http://www.ideone.com/VJnck

但是它会typeof_<U> enabled<T>所有实例化的typeof_<int>朋友的所有实例化,这意味着enabled<T>T的朋友template<typename T> class enabled { private: T type_; friend const T& typeof_(const enabled<T>& obj) { return obj.type_; } }; 的所有可能值反之亦然。

因此,更好的解决方案是使函数非模板在类中定义它:

typeof

演示:http://www.ideone.com/Rd7Yk

请注意,我将typeof_替换为typeof,因为GCC的扩展名为{{1}},因此它在ideone上出错(因为我无法关闭扩展名)。