模板类复制内部类问题中的模板赋值运算符

Posted

技术标签:

【中文标题】模板类复制内部类问题中的模板赋值运算符【英文标题】:Template assignment operator in template class copying inner class issue 【发布时间】:2016-09-03 23:43:26 【问题描述】:

我有一个包含内部类的模板类。在 operator=() 重载上,我想复制内部类的一个实例,但出现错误:

no known conversion from 'const foo<double>::bar' to 'const foo<int>::bar'

代码看起来像(你可以找到一个例子here):

template<typename T>
class foo 
public:
    template<typename>
    friend class foo;

    class bar 
        std::string inner_str;
    public:
        bar const& operator=(bar const& r) 
            inner_str = r.inner_str;
            return *this;
        
    ;

    template<typename F>
    foo const& operator=(foo<F> const& r) 
        value = static_cast<T>(r.value);
        str_container = r.str_container;
        return *this;
    

private:
    bar str_container;
    T value;
;

bar 移到foo 之外可以正常工作,但内部类应该是foo 的一部分。

如何解决这个问题?我想过让bar 像 foo 这样的朋友成为 foo 的所有专业的朋友。但是不知道怎么介绍。

旁注:请随意更改标题,因为我真的不知道如何命名这个特定问题。

【问题讨论】:

应该foo&lt;A&gt;::bar 是与foo&lt;B&gt;::bar 无关的类型吗?如果没有,您可以创建一个以 bar 作为内部类型的基类,并从中派生您的 foo&lt;T&gt; 实例。 好主意,但这也需要 foo 之外的类。还有其他可能吗? 你为什么不想要foo之外的课程? 所以我们很清楚,我说的是this。 foo 是一种在不同组件之间共享的接口。简单地说,如果界面包含所有内容,而不是将它们分开,那就太好了。如果不可能,那么如果 bar 在外面就好了,但我认为在 c++ 中应该是可能的,我只是错过了一些东西。也很高兴知道该怎么做。 【参考方案1】:

foo&lt;double&gt;::bar 是与const foo&lt;int&gt;::bar 完全无关的类型,因此您无法在它们之间进行隐式转换。

由于bar 似乎不依赖于模板参数,这似乎是一个明智的解决方案:

在 foo 外面移动 bar 可以正常工作

问题解决了:)

但内部类应该是foo 的一部分。

考虑到你如何使用它,我认为不,它不应该是 foo 的一部分。

或者,您可以将 bar 的赋值运算符设为模板,就像使用 foo 的赋值运算符一样:

template<typename B>
bar const& operator=(const B& r) 
    inner_str = r.inner_str;
    return *this;

template<typename U>
friend class foo<U>::bar; // this bar must be friends with other bars

如果bar 的定义确实依赖于foo 的模板参数,那么您可以使用这种方法。否则,在每个 foo 中定义一个相同但独立的内部类就没有多大意义。

【讨论】:

我会尝试另一种方法并让您知道。 @user1810087 我用可行的方法更新了替代方法。 补充一点:如果 bar 在 foo 中只是为了保持组织(不污染全局命名空间与 bar 仅由 foo 使用)使用非模板基类或命名空间来保存 foo 和bar 然后将 foo 暴露在该内部命名空间之外。 有趣的是,clang 正在生成警告 (warning: dependent nested name specifier 'foo&lt;U&gt;::' for friend class declaration is not supported; turning off access control for 'bar' [-Wunsupported-friend] friend class foo&lt;U&gt;::bar;),而 gcc 和 Visual Studio 则不会。但除此之外,它工作正常。谢谢。

以上是关于模板类复制内部类问题中的模板赋值运算符的主要内容,如果未能解决你的问题,请参考以下文章

模板类赋值运算符类

包含指向派生模板类的基类指针的类的赋值运算符和复制构造函数

如何为从C++中的模板继承的类重载赋值运算符

模板类的赋值运算符

模板类的重载赋值运算符

永恒赋值运算符调用循环C++模板类