【问题标题】:Class template befriending function template类模板交友函数模板
【发布时间】:2011-10-29 18:03:19
【问题描述】:

当我尝试从以下代码创建可执行文件时出现链接器错误。我觉得我需要在周围放置一些“typenames”或进行一些前向声明;我尝试了几种组合,但都没有奏效。

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>main.obj : error LNK2001: unresolved external symbol "class std::string const& __cdecl typeof(class enabled const&)"

【问题讨论】:

  • gcc 似乎提供了更有用的诊断 [我将 typeof 更改为 type,因为 gcc 有 typeof 扩展名]:prog.cpp:17:警告:朋友声明 'const T& type (const enabled&)' 声明了一个非模板函数 prog.cpp:17: 注意: (如果这不是你想要的,请确保函数模板已经被声明并在函数名后面添加 ) 但是,不确定如何将其转化为解决方案。

标签: c++ templates


【解决方案1】:

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

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

【讨论】:

    【解决方案2】:

    问题是类友函数不是函数模板,而你实际定义的函数是函数模板。

    你需要做的就是让朋友成为一个函数模板:

    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_&lt;U&gt; 的所有实例化为enabled&lt;T&gt; 的所有实例化的朋友,这意味着对于T 的所有可能值,typeof_&lt;int&gt;enabled&lt;T&gt; 的朋友,反之亦然。

    所以更好的解决方案是让函数非模板在类中定义为:

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

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

    请注意,我将 typeof 替换为 typeof_,因为 GCC 有一个名为 typeof 的扩展名,因此在 ideone 上出现错误(因为我无法关闭扩展名)。

    【讨论】:

    • 不会让整个模板成为朋友吗?我只希望模板的特定实例成为朋友。
    • typeof 是保留关键字吗?我宁愿使用type_of,而不是typeof_
    猜你喜欢
    • 2010-12-19
    • 2011-07-30
    • 1970-01-01
    • 2016-10-19
    • 2013-09-18
    • 1970-01-01
    • 1970-01-01
    • 2015-03-11
    相关资源
    最近更新 更多