Reputation: 2617
this code here is my attempt to define a template to typecast or assignment operator. Problem is, this is not calling typecast function template at line 27 while typecasting the object.
#include <iostream>
#include <string>
using namespace std;
struct FFJSON{
template <typename T>
FFJSON& operator=(T const& t){
cout << "Assigning the object" << endl;
ts=(void*)&t;
return *this;
};
FFJSON& operator=(const char* s){return *this;};
FFJSON& operator=(const string& s){return *this;};
FFJSON& operator=(const int& i){return *this;};
FFJSON& operator=(const unsigned int& i){return *this;};
template <typename T>
operator T(){
cout << "Returning the object." << endl;
return *ts;
}
void* ts;
};
int main(int argh, char** argv) {
FFJSON f;
timespec tt = {3,2};
f = tt;
timespec& t=(timespec&)f;
cout << "sec:"<<t.tv_sec<<endl;
cout << "usec:"<<t.tv_nsec<<endl;
return 0;
}
Actual output:
Assigning the object
sec:126885484802960
nsec:4197094
Expected output:
Assigning the object
Returning the object
sec:3
nsec:2
The similar scenario is giving typecast operator not defined compile time error in an another program.
Upvotes: 0
Views: 206
Reputation: 1811
timespec& t=(timespec&)f;
cannot use the typecast operator because you are casting to timespec&
and not to timespec
.
You have to implement
operator T&(){
cout << "Returning the object." << endl;
return *reinterpret_cast<T*>(ts);
}
to make this work.
Please do not use C-style casts in C++ modules. Use static_cast<>
, dynamic_cast<>
, reinterpret_cast<>
and - if you really have to - const_cast<>
instead.
I am not sure what you are trying to achieve, but the following implementation of the assignment operator copies the source value and should work for temporary objects and the typecast operator checks if the conversion may be valid.
class FFJSON
{
public:
template <typename T>
inline FFJSON& operator=(T const& t){
cout << "Assigning the object" << endl;
assert(std::is_trivially_copyable<T>::value );
data.resize(sizeof(t));
*reinterpret_cast<T*>(data.data()) = t;
return *this;
};
template <typename T>
inline operator T(){
cout << "Returning the object." << endl;
assert(sizeof(T) <= data.size());
return *reinterpret_cast<T*>(data.data());
}
private:
std::vector<char> data;
};
Upvotes: 2
Reputation: 119089
template <typename T> operator T()
is fine, but such T
can only be deduced to a non-reference type so this operator will not be used to convert to the type timespec&
. Instead, your cast is a reinterpret_cast
, which never performs a user-defined conversion.
In order to write a conversion operator that can produce an lvalue, you would need to write template <typename T> operator T&()
.
BTW, you can't dereference a void pointer. If your operator template were ever instantiated, you would get a compilation error because of that.
Upvotes: 3