I'm trying to make a type which can type-safely encapsulate arbitrary types. I got the idea in my head that this might be possible from this answer: 5 years later, is there something better than the "Fastest Possible C++ Delegates"? So far I have only succeeded in moving the problem, but I ran into an error that I can't find the root of.
The compiler seems to be telling me that it can't cast the value to the value's own type, which strikes me as bizarre.
I am running Mac OS X 10.6 with llvm-gcc 4.2 (gcc 4.2.1 front-end).
Suggestions of how to get rid of the void* or move it to a less consequential position are welcome, but this question isn't really about that.
The error:
$ g++ main.cpp
main.cpp: In static member function ‘static Stamp StampFactory<T>::make(T*) [with T = int]’:
main.cpp:33: instantiated from ‘Stamp makeStamp(T*) [with T = int]’
main.cpp:39: instantiated from here
main.cpp:26: error: could not convert template argument ‘t’ to ‘int*’
The code:
typedef void (*VoidFunc)(void*);
struct Stamp
{
Stamp(VoidFunc p)
{
this->press = p;
}
VoidFunc press;
};
template<typename T>
struct StampFactory
{
template<T* rvalue>
struct Pattern
{
void operator()(void* lvalue)
{
*dynamic_cast<T*>(lvalue) = *rvalue;
}
};
static Stamp make(T* t)
{
return Stamp(Pattern<t>()); // 28
}
};
template<typename T>
Stamp makeStamp(T* t)
{
return StampFactory<T>::make(t); // 33
}
int main(int argc, char** argv)
{
int i = 0;
Stamp s = makeStamp(&i); //39
}
The error is due to the fact that template arguments must be compile-time constants (or constexpr
), and thus, cannot be a variable (or function parameter). It is allowed to have a pointer as a template argument, but there isn't much that you can feed to it because it needs to be a compile-time constant pointer value (and the only thing I can think of that qualifies is a char-pointer to a string literal). The general rule is simple: All template arguments must be known at compile-time, whether it is a type or a value. This excludes function parameters or other kinds of run-time variables.
I wish I could suggest an alternative to achieve what you desire, but I can't understand what you are actually trying to do at all.