Consider the following code:
<code>#include<iostream>
// #### This is my code, I can alter it.
struct A;
template<typename T> struct B;
template<typename T>
A operator=(B<T> const&);
// think of this as my custom vec3 implementation.
template<typename T>
class B{
friend A operator=(B<T> const&);
T j;
public:
B(T j):j(j){}
};
// #### This is code of somebody else's github library. I cannot alter it. Think of it as GLM.
// think of this as glm::vec3 .
struct A{
int i;
A(int i=0):i(i){}
A()=default;
A(A&&)=default;
A(A const&)=default;
constexpr A& operator=(A const&)=default;
constexpr A& operator=(A&&)=default;
};
// #### This is my code, I can alter it.
// usually, I cannot cast my custom vec3, so it will be empty
template<typename T> A operator=(B<T> const& b){ return A(); }
// but under special cases it is just fine
A operator=(B<int> const& b){ return A(b.j); }
int main(){
B<int> b(3);
A a;
a = b; // as consumer I want to be able to simply assign like so.
std::cout << a.i << "n";
}
</code>
<code>#include<iostream>
// #### This is my code, I can alter it.
struct A;
template<typename T> struct B;
template<typename T>
A operator=(B<T> const&);
// think of this as my custom vec3 implementation.
template<typename T>
class B{
friend A operator=(B<T> const&);
T j;
public:
B(T j):j(j){}
};
// #### This is code of somebody else's github library. I cannot alter it. Think of it as GLM.
// think of this as glm::vec3 .
struct A{
int i;
A(int i=0):i(i){}
A()=default;
A(A&&)=default;
A(A const&)=default;
constexpr A& operator=(A const&)=default;
constexpr A& operator=(A&&)=default;
};
// #### This is my code, I can alter it.
// usually, I cannot cast my custom vec3, so it will be empty
template<typename T> A operator=(B<T> const& b){ return A(); }
// but under special cases it is just fine
A operator=(B<int> const& b){ return A(b.j); }
int main(){
B<int> b(3);
A a;
a = b; // as consumer I want to be able to simply assign like so.
std::cout << a.i << "n";
}
</code>
#include<iostream>
// #### This is my code, I can alter it.
struct A;
template<typename T> struct B;
template<typename T>
A operator=(B<T> const&);
// think of this as my custom vec3 implementation.
template<typename T>
class B{
friend A operator=(B<T> const&);
T j;
public:
B(T j):j(j){}
};
// #### This is code of somebody else's github library. I cannot alter it. Think of it as GLM.
// think of this as glm::vec3 .
struct A{
int i;
A(int i=0):i(i){}
A()=default;
A(A&&)=default;
A(A const&)=default;
constexpr A& operator=(A const&)=default;
constexpr A& operator=(A&&)=default;
};
// #### This is my code, I can alter it.
// usually, I cannot cast my custom vec3, so it will be empty
template<typename T> A operator=(B<T> const& b){ return A(); }
// but under special cases it is just fine
A operator=(B<int> const& b){ return A(b.j); }
int main(){
B<int> b(3);
A a;
a = b; // as consumer I want to be able to simply assign like so.
std::cout << a.i << "n";
}
Question
What is the best problem to realizing the intended consumer semantics, given I am prohibited from defining the assignment operator like so? Notice I have no way to affect the library GLM. In my actual scenario, I wrote a custom quaternion and want to assign it to glm::quat.
2