超载操作员=在模板类型之间切换

发布于 2025-02-08 09:22:39 字数 1581 浏览 2 评论 0 原文

我有一个模板类,其中多个类正在继承,从根本上制造了一些用户友好的构建器,从而隐藏了在干燥时在不同构建器上不需要的功能。

但是,我在构建器类型之间切换时遇到了麻烦。我宁愿使用 operator = 切换而不麻烦,并具有以下代码。

template<class T> class BuilderFunctions
{
protected:
    std::string text;

public:
    template<class Other>
    BuilderFunctions<T>& operator=(const Other& other);
};

template <class T>
template <class Other>
BuilderFunctions<T>& BuilderFunctions<T>::operator=(const Other& other)
{
    // yes, I need same object protection
    text = other.text;
    return *this;
}

我可能会做我不应该在模板类


class BuilderGenericList : public BuilderFunctions<BuilderGenericList> 
{
public:
    BuilderGenericList() = default;
};

// Build configuration details
class BuilderRootList : public BuilderFunctions<BuilderRootList>
{
private:
    // I'll delete the functions I don't want accessed here

public:
    BuilderRootList() = default;
};

除了

// Real world you'd build the root first and switch out to another builder or be using a prototype to seed another builder
BuilderRootList cmakeRoot;
BuilderGenericList list;

// Separate to make sure it's not trying to use cop constructor
list = cmakeRoot;

中做的事情,尽管其他人似乎在操作员中取得了成功,所以我可能会假设某种错误。


更多信息:我遇到的错误是:

Error   C2679   binary '=': no operator found which takes a right-hand operand 
of type 'BuilderRootList' (or there is no acceptable conversion)

因此,它肯定是在寻找我的 operator = ,它只是没有从模板中生成一个

I have a template class that multiple classes are inheriting from to basically make some user-friendly builders, hiding the functions that are not required on different builders, while following DRY.

However, I'm having trouble switching between the builder types. I'd prefer to use the operator= to switch without hassle and have the following code.

template<class T> class BuilderFunctions
{
protected:
    std::string text;

public:
    template<class Other>
    BuilderFunctions<T>& operator=(const Other& other);
};

template <class T>
template <class Other>
BuilderFunctions<T>& BuilderFunctions<T>::operator=(const Other& other)
{
    // yes, I need same object protection
    text = other.text;
    return *this;
}

Classes


class BuilderGenericList : public BuilderFunctions<BuilderGenericList> 
{
public:
    BuilderGenericList() = default;
};

// Build configuration details
class BuilderRootList : public BuilderFunctions<BuilderRootList>
{
private:
    // I'll delete the functions I don't want accessed here

public:
    BuilderRootList() = default;
};

Code that says no

// Real world you'd build the root first and switch out to another builder or be using a prototype to seed another builder
BuilderRootList cmakeRoot;
BuilderGenericList list;

// Separate to make sure it's not trying to use cop constructor
list = cmakeRoot;

Except I might be doing something I shouldn't be doing with template classes, although others seem to have success with templates in the operators, so assume possible, and I'm making some kind of mistake.


More info: The error I get is:

Error   C2679   binary '=': no operator found which takes a right-hand operand 
of type 'BuilderRootList' (or there is no acceptable conversion)

So It's definitely looking for my operator=, it's just not generating one from the template

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

苄①跕圉湢 2025-02-15 09:22:39

当您执行模板继承时,必须在基本类成员的情况下明确说明。 More read:

在您的情况下,成员 text operator = ,可以是使用声明通过带来。

class BuilderGenericList : public BuilderFunctions<BuilderGenericList> 
{
public:
    BuilderGenericList() = default;
    using BuilderFunctions<BuilderGenericList>::text;
    using BuilderFunctions<BuilderGenericList>::operator=;
    // ... so on, other members from base if needed!
};

// Build configuration details
class BuilderRootList : public BuilderFunctions<BuilderRootList>
{
public:
    BuilderRootList() = default;
    using BuilderFunctions<BuilderRootList>::text;
    using BuilderFunctions<BuilderRootList>::operator=;
    // ... so on, other members from base if needed!
};

live demo

请注意,这将使成员使用builderFunctions&lt;文本公开,如果不是想要的,请在其他答案中考虑@jarod42 的建议。

When you do the template inheritance, you have to be explicit in case of base classes members. More read:

In your case, the members text, and operator=, can be brought via using declaration.

class BuilderGenericList : public BuilderFunctions<BuilderGenericList> 
{
public:
    BuilderGenericList() = default;
    using BuilderFunctions<BuilderGenericList>::text;
    using BuilderFunctions<BuilderGenericList>::operator=;
    // ... so on, other members from base if needed!
};

// Build configuration details
class BuilderRootList : public BuilderFunctions<BuilderRootList>
{
public:
    BuilderRootList() = default;
    using BuilderFunctions<BuilderRootList>::text;
    using BuilderFunctions<BuilderRootList>::operator=;
    // ... so on, other members from base if needed!
};

Live Demo

Note that, this will make the memberusing BuilderFunctions<BuilderGenericList>::text public, if this is not what wanted, consider the suggestion by @Jarod42 in other answer.

无力看清 2025-02-15 09:22:39

builderFunctions&lt; t1&gt; 无法访问 private /受保护 builderFunctions&lt; t2&gt; (带有 t1 t1 ) /code>!= t2 ):添加访问者,或使它们 friend

此外,您还必须使用 operator =

template<class T>
class BuilderFunctions
{
    template <typename U> friend class BuilderFunctions;
protected:
    std::string text;

public:
    template<class Other>
    BuilderFunctions<T>& operator=(const Other& other);
};

template <class T>
template <class Other>
BuilderFunctions<T>& BuilderFunctions<T>::operator=(const Other& other)
{
    //yes, I need same object protection
    text= other.text;
    return *this;
}


class BuilderGenericList : public BuilderFunctions<int>{
public:
    using BuilderFunctions<int>::operator=;

    BuilderGenericList() = default;
};

//Build configuration details
class BuilderRootList : public BuilderFunctions<float>
{
private:
//I'll delete the functions I don't want accessed here

public:
    using BuilderFunctions<float>::operator=;

    BuilderRootList() = default;
};

demo

BuilderFunctions<T1> cannot access private/protected member of BuilderFunctions<T2> (with T1 != T2): add accessor, or make them friend.

in addition, you also have to put using for operator=:

template<class T>
class BuilderFunctions
{
    template <typename U> friend class BuilderFunctions;
protected:
    std::string text;

public:
    template<class Other>
    BuilderFunctions<T>& operator=(const Other& other);
};

template <class T>
template <class Other>
BuilderFunctions<T>& BuilderFunctions<T>::operator=(const Other& other)
{
    //yes, I need same object protection
    text= other.text;
    return *this;
}


class BuilderGenericList : public BuilderFunctions<int>{
public:
    using BuilderFunctions<int>::operator=;

    BuilderGenericList() = default;
};

//Build configuration details
class BuilderRootList : public BuilderFunctions<float>
{
private:
//I'll delete the functions I don't want accessed here

public:
    using BuilderFunctions<float>::operator=;

    BuilderRootList() = default;
};

Demo

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文