Dodawanie różnych szablonów

0

Mam pytanie odnośnie poniższego kodu.

template <typename T>
class A
{
private:
    T m_val;

public:
    A(T m)
    {
        this->m_val = m;
    }

    A& operator+=(const A& w)
    {
        this->m_val += w.m_val;
        return *this;
    }
};

int main()
{
    A<float> w1(1.1);
    A<float> w2(2.2);

    w1 += w2;

    A<double> w3(3.3);
    w2 += w3; //Wiadomy błąd, można operować tylko na tych samych szablonach.

    return 0;
}

Gdzie musiałbym zaczerpnąć wiedzy, abym mógł dowiedzieć się jak dodać obiekt z typem float do obiektu z typem double(itd.)?

2

Możesz zrobić coś takiego:

 
    template <typename _Ty2>
    A& operator+=(const A<_Ty2>& w)
    {
    	this->m_val += w.m_val;
        return *this;
    }
  • T m_val; musi być publiczny albo musi być getter użyty, ponieważ próbujesz odwołać się do zmiennej prywatnej innego typu.
0

Dzięki, gra i buczy.

Jeszcze jedno pytanko. Dlaczego nie można wywołać gettera na obiekcie const?

    template <typename _Ty2>
    A& operator+=(const A<_Ty2>& w)
    {
        this->m_val += w.get();  // wywali błąd, ale jak usunę "const" gra i buczy.
        return *this;
    }
1
template <typename T>
class A
{
private:
    T m_val;
 
public:
    ....

    T get() const
    {
        return m_val;
    }
};

Gettera też musisz zrobić const

0

Pojawił się kolejny problem.

template <typename T, unsigned C>
class A
{
private:
    T m_val;

public:
    A(T m)
    {
        this->m_val = m;
    }

    T get() const
    {
        return m_val;
    }

    template <typename _Ty2, unsigned C2>
    A& operator+=(const A<_Ty2, C2>& w)
    {
        this->m_val += w.get();
        return *this;
    }
};

int main()
{
    A<double, 2> w2(2.2);
    A<double, 3> w3(3.3);

    w3 += w2; //Powinno wywalić błąd

    return 0;
}

W jaki sposób mogę rozkazać kompilatorowi, aby rozróżniał wartości w drugim parametrze template?
Chodzi mi o to, że

    A<double, 2> w2(0);
    A<double, 3> w3(0);

    w3 += w2; //Powinno wywalić błąd

Ponieważ w drugim parametrze 3!=2, a niestety po dodaniu template <typename _Ty2, unsigned C2> nie jest to "rozróżniane. Jak zapobiec temu?

W skrócie mówiąc, ma być wykonywane dodawanie, gdy:
-w pierwszym parametrze będzie dowolny typ(nawet różne)
-drugi parametr musi się zgadzać np.(A<double, 2> w2(0); A<double, 2> w3(0);)

1
template <typename T, unsigned C>
class A
{
private:
    T m_val;
 
public:
    A(T m)
    {
        this->m_val = m;
    }
 
    T get() const
    {
        return m_val;
    }
 
    template <typename _Ty2>           // Wywal typ C2
    A& operator+=(const A<_Ty2, C>& w) // .. zmień na C
    {
        this->m_val += w.get();
        return *this;
    }
};
 
int main()
{
    A<double, 2> w2(2.2);
    A<double, 3> w3(3.3);
 
    w3 += w2; // Powinno wywalić błąd
 
    return 0;
}
1

Odpowiedź to type_traits i std::enable_if jeżeli korzystasz C++11 w górę, odpowiednik jest też w Boost.

    
   #include <type_traits>
    
    template <typename _Ty2, unsigned C2, typename = typename std::enable_if<C2==C>::type>
    A& operator+=(const A<_Ty2, C2>& w)
    {
    	
        this->m_val += w.get();
        return *this;
    }
};

EDIT: no tak, przekombinwałem, tutaj akurat zmiana C2 na C wystarczy :)

0

@Mokrowski w tym przypadku idealnie pasuje to rozwiązanie. Dzięki.
@alagner troszkę przekombinowany sposób(jak sam napisałeś), ale także przydatny w innych wyjątkowych sytuacjach(np. przy >, < itp.). Dzięki ;)

1 użytkowników online, w tym zalogowanych: 0, gości: 1