【问题标题】:Overloading operator in different ways depending on template argument根据模板参数以不同方式重载运算符
【发布时间】:2021-12-28 13:17:21
【问题描述】:

我有课

template<int n> MyClass<n>

我正在尝试为其定义operator &amp;。我希望能够执行 MyClass&MyClass,而且 MyClass&MyClass(或者 MyClass&MyClass 也适用于我)显然具有不同的功能。

template <size_t n>
struct MyClass
{
    //...a lot of stuff
    MyClass<n> operator&(const MyClass<n> &other) const;

    MyClass<n> operator&(const MyClass<1> &other) const;
}

但是,我无法编译这个,至于 n 为 1 的情况它们会发生冲突。我尝试添加 SFINAE,但显然我对它的理解不够充分,无法在这种情况下使用它。

template <size_t n>
struct MyClass
{
    //...a lot of stuff
    MyClass<n> operator&(const MyClass<n> &other) const;

    std::enable_if_t<n != 1, MyClass<n>> operator&(const MyClass<1> &other) const;
}

不能确保 n 为 1 的情况不会导致问题。我认为这是因为 SFINAE 适用于函数模板参数本身,而不适用于类模板参数。

我相信我可以专门化MyClass&lt;1&gt;,但是我必须复制MyClass&lt;n&gt; 的所有内容。有什么简单的解决办法吗?

【问题讨论】:

    标签: c++ templates


    【解决方案1】:

    SFINAE 仅适用于模板。您可以将第一个operator&amp; 模板设为:

    template <size_t n>
    struct MyClass
    {
        //...a lot of stuff
        template <size_t x>
        std::enable_if_t<x == n, MyClass<x>> // ensure only MyClass<n> could be used as right operand 
        operator&(const MyClass<x> &other) const;
    
        // overloading with the template operator&
        // non-template is perferred when MyClass<1> passed
        MyClass<n> operator&(const MyClass<1> &other) const;
    };
    

    LIVE

    【讨论】:

    • 这真的很有趣! 1==x==n 没有问题的原因是什么?您写它是因为首选非模板,但为什么在我的第一个示例中不是这种情况?
    • @DottyPhone 在您的示例中,operator&amp; 都是非模板并采用 const MyClass&lt;1&gt; &amp;,它们具有确切的签名,您将收到重新声明错误。在我的代码中,一个是模板,另一个是非模板;它们的签名不同,然后重载。
    • 哦,我明白了!没错,就我而言,n 来自班级 :) 我错过了,谢谢
    【解决方案2】:

    可以使用约束(需要c++20)

    template <size_t n>
    struct MyClass
    {
        MyClass<n> operator&(const MyClass<n> &) const { std::cout << "1\n"; return {}; }
        MyClass<n> operator&(const MyClass<1> &) const requires (n!=1) { std::cout << "2\n"; return {}; }
    };
    

    【讨论】:

    • 不使用 c++20 但他们添加了这个很棒!
    【解决方案3】:

    小心操作符重载,不要给操作符赋予超出预期的含义。在几乎所有情况下,最好创建具有​​可读名称的函数(为了便于维护)。

    你想做什么我认为可以用“if constexpr”来完成,例如:

    #include <utility>
    #include <iostream>
    
    template <std::size_t N>
    struct MyClass
    {
        void do_something() const
        {
            if constexpr (N == 1)
            {
                std::cout << "behavior 1\n";
            }
            else
            if constexpr (N == 2)
            {
                std::cout << "behavior 2\n";
            }
        }
    };
    
    int main()
    {
        MyClass<1> c1;
        MyClass<2> c2;
    
        c1.do_something();
        c2.do_something();
    
        return 0;
    }
    

    【讨论】:

      猜你喜欢
      • 2021-02-17
      • 1970-01-01
      • 1970-01-01
      • 2020-02-07
      • 1970-01-01
      • 2012-04-26
      • 2015-09-15
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多