Hi I am new in C++ templates, need some help with it. Code below kind of static polymorphism. Problem with Token type that, double calls Token constructor and destructor. How achieve one call for constructor, destructor.
#include <iostream>
#include <vector>
template<typename T> class Scalar {
private:
T s;
public:
using value_type = T;
Scalar (T const& v): s{v} {std::cout<<"Scalar const\n";}
~Scalar() { std::cout<<"Scalar destruct\n";}
T const& operator [] (size_t) const { return s; }
size_t size() const { return 0; }
};
template<typename T> class Token: private T {
public:
using value_type = T::value_type;
Token (typename T::value_type val): T(val) { std::cout<<"token constructor\n"; }
Token (Token const& rhs) = delete;
Token (Token&& rhs) =default;
~Token () { std::cout<<"token destruct\n"; }
decltype(auto) operator [] (size_t idx) const
{ std::cout<<"token const ref\n"; return static_cast<T const*>(this)->operator[](idx); }
};
template<typename T> std::vector<Token<T>> tokens;
template<typename T> void add_scalar (T value) {
tokens<Token<Scalar<T>>>.emplace_back(value);
std::cout<<"val " << tokens<Token<Scalar<T>>>[0][0]<<'\n';
}
int main () {
add_scalar<int>(10);
}
That return
Scalar const
token constructor
token constructor
token destruct
token destruct
Scalar destruct
tokens<Token<Scalar<T>>>
is a std::vector<Token<Token<Scalar<T>>>>
. This means when you .emplace_back(value)
, you create a Token<Token<Scalar<T>>>
that holds a Token<Scalar<T>>
as a base class, so there are two Token<...>
objects.
It might be a bit more clear if you spelled out the template types in the functions (https://godbolt.org/z/4Kd4e9b6K):
Scalar<int>(int const&) constructor
Token<Scalar<int>>(int) constructor
Token<Token<Scalar<int>>>(int) constructor
Token<Token<Scalar<int>>> destruct
Token<Scalar<int>> destruct
Scalar<int> destruct
Two constructor calls and destructor calls would be the lowest amount to add an item to tokens<Token<Scalar<T>>>
. Though the double Token<Token<...>>
is a bit fishy, perhaps you meant tokens<Scalar<T>>
.