#include <iostream>
class Student {
public:
Student( int id ) : m_id(id) {
std::cout << "Called constructor: int -> Student\n";
}
Student( unsigned short id ) : m_id(static_cast<unsigned short>(id)) {
std::cout << "Called constructor: unsigned short -> Student\n";
}
operator short();
operator long();
private:
int m_id;
};
Student::operator short(){
std::cout << "Called conversion function: Student -> short\n";
return static_cast<short>(m_id);
}
Student::operator long(){
std::cout << "Called conversion function: Student -> long\n";
return static_cast<unsigned short>(m_id);
}
int main(){
short id = 0;
// Standard conversion (promotion): short to int
// Constructor: convert int to Student
Student daniel(id);
// User-defined conversion: convert Student to short
// Standard conversion (promotion): short to int
int fid = daniel;
std::cout << "fid = " << fid << "\n";
return 0;
}
#include <iostream>
class Teacher; // Forward declaration for use in Student
class Student {
public:
Student(Teacher& t); // Constructor taking Teacher&
void show() const {
std::cout << "Student created with ID = " << m_id << std::endl;
}
private:
int m_id;
};
class Teacher {
public:
Teacher(int id) : m_id(id) {}
// User-defined conversion from Teacher to Student
operator Student() {
std::cout << "Converting Teacher to Student...\n";
return Student(*this); // Uses Student(Teacher&) constructor
}
int getID() const { return m_id; }
private:
int m_id;
};
// Define Student constructor after Teacher is fully defined
Student::Student(Teacher& t) : m_id(t.getID()) {}
int main() {
Teacher t1(42);
// Implicit conversion: Teacher → Student using Teacher::operator Student()
// Implicit conversion: Teacher → Student using Student::Student( Teacher& )
Student s1 = t1; // Error: ambiguous
// Explicit conversion also possible
Student s2 = static_cast<Student>(t1);
s2.show();
return 0;
}
However, the version below is ambigous as Box::operator SimplePolygon<int> was not instantiated.
#include <iostream>
template<typename C>
class SimplePolygon;
template<typename C>
class Box {
public:
Box(C x, C y) : _x(x), _y(y) {}
template<typename D>
operator SimplePolygon<D> (){
std::cout << "Calls Box::operator\n";
return { _x, _y };
}
C getX() { return _x; }
C getY() { return _y; }
private:
C _x;
C _y;
};
template<typename C>
class SimplePolygon {
public:
SimplePolygon(Box<C>& box) : _x(box.getX()), _y(box.getY()) { std::cout << "Calls SimplePolygon()\n"; }
private:
C _x;
C _y;
};
int main() {
Box<int> box(1,2);
// Calls SimplePolygon()
SimplePolygon<int> sp = box;
return 0;
}
calc(t) appears in class scope (in a member function, for example), the set containing the function declarations visible at the point of the call may contain functions that are not member functions. #include <iostream>
class Student {
public:
Student(short id) : m_id(id) {}
operator float(){ return m_id; }
operator int(){ return m_id; }
void show() const {
std::cout << "Student created with ID = " << m_id << std::endl;
}
private:
short m_id;
};
void addOne( int ia ){
std::cout << "Calls addOne(int)\n";
std::cout << "ia = " << ia+1 << "\n";
};
void addOne( double fa ){
std::cout << "Calls addOne(unsigned short)\n";
std::cout << "fa = " << fa+1 << "\n";
};
int main() {
Student daniel(static_cast<short>(1));
// addOne(int) : Student -> int -> int (exact match)
// addOne(float): Student -> float -> double (conversion)
addOne(daniel); // Error: ambiguous
return 0;
}
#include <iostream>
class Student {
public:
Student(short id) : m_id(id) {}
operator short(){ return m_id; }
void show() const {
std::cout << "Student created with ID = " << m_id << std::endl;
}
private:
short m_id;
};
void addOne( int ia ){
std::cout << "Calls addOne(int)\n";
std::cout << "ia = " << ia+1 << "\n";
};
void addOne( unsigned short ia ){
std::cout << "Calls addOne(unsigned short)\n";
std::cout << "ia = " << ia+1 << "\n";
};
int main() {
Student daniel(static_cast<short>(1));
// addOne(int) : Student -> short -> int (promotion)
// addOne(unsigned short): Student -> short -> unsigned short
addOne(daniel);
return 0;
}