[C++]Как написать шаблон?
Нафига члены-то новым типом F параметризовать?
Хз почему, но у меня твой код работает (если дописать типы возвращаемых значений и прочую неинтересную ерунду):
template <typename R>
class complex {
public:
R r, i;
complex(R r_, R i_) : r(r_ i(i_) {}
complex : r(0 i(0) {}
template <typename F> complex<R> operator+(complex<F> &b) {
return complex<R>(r + b.r, i + b.i);
}
template <typename F> complex<R> operator+(F b) {
return complex<R>(r + b, i);
}
};
int main(void) {
complex<double> a, b;
complex<int> c, d;
double e;
int f;
a = a + b;
c = c + d;
c = c + a;
a = a + c;
a = b + e;
c = d + f;
}
А ты чем собираешь?
У меня gcc version 4.0.1 (Apple Inc. build 5465 собирается тоже.
template <class T> class complex{
private:
T re_, im_;
public:
complex{}
complex(T re, T im): re_(re im_(im){}
template <class F> complex<T> operator+(const complex<F> &other)
{
return complex(re_ + other.re_, im_ + other.im_);
}
template <class F> complex<T> operator+(const F &other)
{
return complex(re_ + other, im_);
}
};
void f
{
complex<double> a, b;
a = a + b;
}
VS 2008, компилируется.
gcc 4.3.2
template <class T> class complex{
private:
T re_, im_;
public:
complex{}
complex(T re, T im): re_(re im_(im){}
template <class F> complex<T> operator+(const complex<F> &other)
{
return complex(re_ + other.re_, im_ + other.im_);
}
template <class F> complex<T> operator+(F &other)
{
return complex(re_ + other, im_);
}
};
int main
{
complex<double> a, b;
a = a + b;
}
компилятор (проверял на gcc и comeau online) выбирает второй operator+, а если заменить тип параметра на константную ссылку, то выбирает первый?
омпилятор (проверял на gcc и comeau online) выбирает второй operator+быть такого не может
быть такого не можетtest.cpp:
#include <iostream>
template <class T> class complex{
private:
T re_, im_;
public:
complex{}
complex(T re, T im): re_(re im_(im){}
template <class F> complex<T> operator+(const complex<F> &other)
{
return complex(re_ + other.re_, im_ + other.im_);
}
template <class F> complex<T> operator+(F &other)
{
std::cout << "Ooops!" << std::endl;
// return complex(re_ + other, im_);
}
};
int main
{
complex<double> a, b;
a = a + b;
}
mutant ~ $ g++ test.cpp
mutant ~ $ ./a.out
Ooops!
Сам разобрался.
Автор, верни возвращение комплекса, тогда код не будет компилироваться, т.к. не будет констуктора complex(complex, double). Без него второй вариант подходит лучше, т.к. в нём не нужно кастить к константному объекту.
А вот про то, что при выборе перегрузки константность аргумента важнее его типа я не знал
А вот про то, что при выборе перегрузки константность аргумента важнее его типа я не зналА тут уже ты не понял. Во второй перегрухке он считает, что F == complex<double> и потому что complex<double> & - ближе к complex<double>, чем const complex<double> &
Да, верно. Что-то я ступил
[xoft ~]$ cat xxx.cpp
#include <iostream>
using namespace std;
template <class R> struct complex {
complex(R x, R y): x(x y(y) {}
R x;
R y;
};
template <class R, class F>
complex<R> operator+(complex<R> z1, F x2) {
cout << "operator+(complex<R> z1, F x2)" << endl;
return complex<R>(z1.x+x2, z1.y);
}
template<class R, class F>
complex<R> operator+(complex<R> z1, complex<F> z2) {
cout << "operator+(complex<R> z1, complex<F> z2)" << endl;
return complex<R>(z1.x+z2.x, z1.y + z2.y);
}
int main {
complex<double> c(0.5, 0.6);
c + 1;
c + c;
return 0;
}
[xoft ~]$ ./xxx
operator+(complex<R> z1, F x2)
operator+(complex<R> z1, complex<F> z2)
PS. передача параметров по ссылке тоже компилируется.
PSS. gcc version 4.2.3
template <typename F> operator+(complex<F> &b);Вообще старайся писать более общие варианты перед узкоспециализированными.
template <typename F> operator+(F b);
=) это лишь особенность мышления css+xslt программистов, не более
Это хаскель - там более общие идут после тех, что уже. Имхо, так логичнее.
ну я про это и говорил, в хаскеле и похожих языках частное пишут вверху, потому что как бы подразумевается if/elseif/elseif/..., а в css и в xslt пишут общее вверху, подразумевая override-ы. и так и так логично выглядит, не надо из этого каких-то фундаметнальных выводов делать но мне кстати xslt-шный стиль симпатишнее кажется, он применим и при отсутствии локальности, написал override в основной программе и не надо париться, есть какое-то более общее определение в какой-нибудь используемой библиотеке или нет.
=) это лишь особенность мышления css+xslt программистов, не болееВовсе нет, просто специализации шаблонов обязаны идти после описаний более общих определений.
Оставить комментарий
apl13
Забавная такая проблема. Решил, для примера, сделать комплексные числа. Пишу, имея в виду, что одно дело - прибавить к комплексному числу комплексное число, другое дело - прибавить к нему же число вещественное.
Компилятор, встретив
не знает, какой из вариантов сложения взять.
А я не знаю, что ему посоветовать.
Тут можно что-нибудь сделать?