While static member variables can be templated in C++14 this wont work:
class SomeClass
{
public:
template<typename T>
T var = {};
};
int main()
{
SomeClass instance;
instance.var<int> = 50;
instance.var<double> = 0.1;
}
What are the reasons, that templates for variable members are not supported by the C++ standard since it should be possible in principle?
When you instantiate the class you don't know how much memory it will use. Does this class contain an int and a double? What if you write
later in your code
c++ has value types with known sizes. All complete types in C++ that you can create can have their sizes calculated by the compiler based only on information at or above the line of creation within that compilation unit.
In order to do what you want, either the size of instances of a class varies with every template variable ever used in any compilation unit, or the size of instances varies over time as new elements are added.
Now you can create new data based on type, but it won't be inside the class; instead, you add a map storing the data.
now
foo.get<int>()
allocates anint
if it wasn't there, and if it was there gets it. Extra work would have to be done if you want to be able to copy instances.This kind of mess emulates what you want, but its abstraction leaks (you can tell itmisn't a member variable). And it isn't really a template member variable, it just acts a bit like one.
Barring doing something like this, what you ask for is impossoble. And doing this as part of the language would be, quite frankly, a bad idea.
It cannot be possible in principle or in practice, as the other answers explain:
sizeof(SomeClass)
would be impossible to compute in general, andSomeClass
would no longer have any predictable or sane identity, defeating the purpose of its existence.If there are only a select few types you wish to choose from, and you wish to change the "selected" type at runtime, perhaps a variant is what you're looking for?
(This requires C++17, but a Boost equivalent has been available for many, many years.)
It works because
var
will be as big as it needs to to store either anint
or adouble
(plus some housekeeping), and this size is fixed no matter which "mode" your variant is in at any given time.If you want to accept any type, you could use
std::any
, which is like a variant on drugs. The overhead is a little heavier, but if your requirements are really so relaxed then this can do the job.But if you want multiple variables, have multiple variables.
This would make two objects of the same type
SomeClass
different, rendering the class concept as we understand it in c++ useless.Also your code sample implies that
var
could change type during runtime, this can be done using std::variant or std::any.