0

My problem is with operator*. I have two operator* connected with class Wektor. First is for all typenames and is in class Wektor.

friend Wektor operator* (Wektor & a, const int & b)

and second one only for string type and is outside the Wektor class.

template <typename T,int Roz, typename Policy >
Wektor<std::basic_string<char>,Roz,Fast<std::basic_string<char>,Roz> > operator * (Wektor<std::basic_string<char>,Roz,Fast<string,Roz> > & a,int & b)

I want have two operators* wich one is specialized for string and have different behaviour. and whole code below:

//Policy for Wektor
template<typename T,int Roz>
class Safe
{
public:
void static zeroo(T t[]){
            for(int i=0;i<Roz;++i)
            {
                t[i]=0;
            }

}
static bool isOut(int i){
    return Roz<i;
}
};

template<typename T,int Roz>
class Fast
{
public:
void static zeroo(T t[]){
}
static bool isout(int i){
    return false;
}
};


template<typename T,int Roz, typename Policy = Safe<T,Roz> >
class Wektor;

template <typename T,int Roz, typename Policy = Safe<T,Roz> >
Wektor<T,Roz,Policy> operator + (const Wektor<T,Roz,Policy> & a, const Wektor<T,Roz,Policy> & b);

template <typename T,int Roz, typename Policy >
Wektor<std::basic_string<char>,Roz,Fast<std::basic_string<char>,Roz> > operator * (Wektor<std::basic_string<char>,Roz,Fast<string,Roz> > & a, int & b);


template<typename T,int Roz, typename Policy >
class Wektor{
public:

typedef typename typy<T>::result args;
Wektor()
{
    Policy::zeroo(tab);
}
T tab[Roz];
args get(int i)
{
    if (Policy::isout(i)) return 0;
    return tab[i];
}
void set(args val,int i)
{
    if (Policy::isout(i))return;
    tab[i]=val;
}
//This operator works fine
friend Wektor operator* (Wektor & a, const int & b){
      Wektor<T,Roz,Policy> w;

      for(int i=0;i<Roz;++i)
      {
          w.set(a.get(i)*b,i);
      }
      return w;
 }

 friend Wektor operator + <> (const Wektor & a, const Wektor & b);
 };

 template<typename T, int Roz>
 Wektor<T,Roz> operator + (Wektor<T,Roz> & a,Wektor<T,Roz> & b)
 {
 Wektor<T,Roz> wynik;
 for(int i=0;i<Roz;++i)
 {
    wynik.set(a.get(i)+b.get(i),i);
 }
 return wynik;
 }
 //This operator dosent work
 template <typename T,int Roz, typename Policy >
 Wektor<std::basic_string<char>,Roz,Fast<std::basic_string<char>,Roz> > operator *  (Wektor<std::basic_string<char>,Roz,Fast<string,Roz> > & a,int & b)
{
Wektor<string,Roz,Fast<string,Roz> > wynik;
string tmp;
for(int i=0;i<Roz;++i)
{
    for(int j;j<b;++j)tmp.append("asa");
    wynik.set(tmp,i);
    tmp.clear();
}
}

For statement in main():

 Wektor<string,2,Fast<string,2> > str;
 str*3

I get an error at this line:

w.set(a.get(i)*b,i);

In friend operator* wich is whole in class Wektor.

Compiler says: template argument deduction/substitution failed. Rest of compiler notes:

error: no match for 'operator*' in 'Wektor::get(int) with T = std::basic_string; int Roz = 2; Policy = Fast, 2>; Wektor::args = std::basic_string * b'

And more:

note: candidate is: note: template Wektor, Roz, Fast, Roz> > operator*(Wektor, Roz, Fast, Roz> >&, int&)

note: 'Wektor, 2, Fast, 2> >::args {aka std::basic_string}' is not derived from 'Wektor, Roz, Fast, Roz> >'|

And what mean in this context is not derived from? I try to make specialized operator* as firend with class Wektor but this make this same error.

Cœur
  • 37,241
  • 25
  • 195
  • 267
Aku
  • 200
  • 3
  • 9
  • 17
  • Please don't write code in Polish. Also, `std::basic_string` is just `std::string`. Also take a look at [operator overloading FAQ](http://stackoverflow.com/questions/4421706/operator-overloading). – Bartek Banachewicz Apr 16 '13 at 19:25
  • 1
    And make the first parameter of `operator+` and `operator*` a **const** reference. – Daniel Frey Apr 16 '13 at 19:28

1 Answers1

2

As Daniel Frey seems to have noticed in his comment, the first parameter to operator * is a temporary here.

w.set(a.get(i)*b,i);
//    ^^^^^^^^ returns a temporary

C++ will not bind a non-const reference to a temporary.

template <typename T,int Roz, typename Policy >
Wektor<std::basic_string<char>,Roz,Fast<std::basic_string<char>,Roz> > operator * 
  (Wektor<std::basic_string<char>,Roz,Fast<string,Roz> > & a, int & b);

Change it to be const.

template <typename T,int Roz, typename Policy >
Wektor<std::basic_string<char>,Roz,Fast<std::basic_string<char>,Roz> > operator * 
  (const Wektor<std::basic_string<char>,Roz,Fast<string,Roz> > & a, int & b);
// ^^^^^
Community
  • 1
  • 1
Drew Dormann
  • 59,987
  • 13
  • 123
  • 180
  • This dosent solve problem. The main problem is template argument deduction/substitution failed: I have two operator* first is friend Wektor operator* (Wektor & a, const int & b) the second one is template Wektor,Roz,Fast,Roz> > operator * (Wektor,Roz,Fast > & a,int & b). Const add dosent solve problem. How I have to write this operators to avoid deduction/substitution error? – Aku Apr 16 '13 at 20:10
  • Complier always take this friend Wektor operator* (Wektor & a, const int & b) when I want for this instance of Wektor,Roz,Fast > this operator Wektor,Roz,Fast,Roz> > operator * (const Wektor,Roz,Fast > & a, int & b); – Aku Apr 16 '13 at 20:50