C++ - Use default template as base for specialization - c++

I want to write a math vector template. I have a class which accepts type and size as template argument, with a lot of math operation methods.
Now I want to write specializations where Vector<3> for instance has x, y, z as members which refer to data[0..3] respectively.
The problem is that I don't know how to create a specialization which inherits everything from the default template without creating either a base class or writing everything twice.
What's the most efficient way to do this?
template<class Type, size_t Size>
class Vector {
// stuff
};
template<class T>
class Vector<3,T>: public Vector {
public:
T &x, &y, &z;
Vector(): Vector<>(), x(data[0]), y(data[1]), z(data[2]){}
// and so on
};

Somehow you should be able to derive from default implementation, but you are specializing an instance, so how? it should be a non-specialized version that you can be able to derive from it. So that's simple:
// Add one extra argument to keep non-specialized version!
template<class Type, size_t Size, bool Temp = true>
class Vector {
// stuff
};
// And now our specialized version derive from non-specialized version!
template<class T>
class Vector<T, 3, true>: public Vector<T, 3, false> {
public:
T &x, &y, &z;
Vector(): Vector<>(), x(data[0]), y(data[1]), z(data[2]){}
// and so on
};

Consider making this in a little different way, but goals will be achieved, Add external interface - I mean standalone functions X(), Y(), Z():
template<class T, size_t S>
T& x(Vector<T, S>& obj, typename std::enable_if<(S>=1)>::type* = nullptr)
{
return obj.data[0];
}
template<class T, size_t S>
T& y(Vector<T, S>& obj, typename std::enable_if<(S>=2)>::type* = nullptr)
{
return obj.data[1];
}
template<class T, size_t S>
T& z(Vector<T, S>& obj, typename std::enable_if<(S>=3)>::type* = nullptr)
{
return obj.data[2];
}
There is no big difference between:
Vector<T, 3>& obj
return obj.x();
And
Vector<T, 3>& obj
return x(obj);
As a bonus - this interface works for matching sizes.

Related

C++11 variadic template + inheritance

I would like to write an abstraction of linear superpositions using variadic templates. To do that, I would like to define a base type that exhibits a certain form of operator() like so
template <typename Result, typename... Parameters>
class Superposable {
public:
typedef Result result_t;
void operator()(Result& result, const Parameters&...) const = 0;
};
then inherit from it for the current problem, for instance like so
class MyField : public Superposable<double, double, double> {
public:
void operator()(double& result, const double& p1, const double& p2) const {
result = p1 + p2;
}
};
And I would then like to write an abstract base class that can form linear superpositions and gets the Superposable-derived class as a template parameter to determine the call signature of operator(). I would like to have something like
template<typename S> // where S must be inherited from Superposable
class Superposition {
private:
std::vector< std::shared_ptr<S> > elements;
public:
// This is the problem. How do I do this?
void operator()(S::result_t& result, const S::Parameters&... parameters) const {
for(auto p : elements){
S::result_t r;
p->operator()(r, parameters);
result += r;
}
}
};
Here are my questions:
How do I read out the type information from the Superposable-derived class to define my operator() in Superposition?
Also, is there a recommended way to enforce that Superposition can only be called with a Superposable-derived class as an argument?
An even nicer solution would of course be to write a Superposition class that does not require MyField to be derived from a base class, but directly parses MyField's operator(). Can I do this somehow?
Thanks for your help!
First, a solution to your problem directly.
Some metaprogramming boilerplate:
template<class...>struct types{using type=types;};
A hana-style function that extracts the types of an argument, optionally taking a template from which to do the extraction based on:
template<template<class...>class Z, class...Args>
constexpr types<Args...> extract_args( Z<Args...> const& ) { return {}; }
An alias that wraps the above in a decltype for ease of use:
template<template<class...>class Z, class T>
using extract_args_from = decltype( extract_args<Z>( std::declval<T>() ) );
The primary template of Superposition is left empty, with a default argument that extracts the type arguments of Superposable:
template<class S, class Args=extract_args_from<Superposable, S>>
class Superposition;
then a specialization that gets the Result and Parameters types of the (possibly base class of) S's Superposable:
template<class S, class Result, class...Parameters>
class Superposition< S, types<Result, Parameters...>> {
live example. Btw, you missed a virtual.
Note that I don't approve of your design -- the result should be the return value (naturally), making () virtual seems like a bad idea (I'd use CRTP instead, and type-erase if I really need to hide the particular implementation).
You can remove the body of Superposable and it works as-is:
public:
typedef Result result_t;
void operator()(Result& result, const Parameters&...) const = 0;
which I'd recommend at the least.
The next step is to get rid of inheritance and deducing Parameters at all:
class MyField {
public:
double operator()(const double& p1, const double& p2) const {
return p1 + p2;
}
};
template<typename S> // where S must be inherited from Superposable
class Superposition {
private:
std::vector< std::shared_ptr<S> > elements;
public:
template<class...Parameters,
class R=std::result_of_t<S&(Parameters const&...)>
>
R operator()(const Parameters&... parameters) const {
R ret = {};
for(auto p : elements){
ret += (*p)(parameters...);
}
return ret;
}
};
which has all the flaws of perfect forwarding, but all the advantages as well.
std::result_of_t<?> is C++14, but replace it with typename std::result_of<?>::type in C++11 as a drop-in.
template <typename Result, typename... Parameters>
class Superposable
{
public:
using result_t = Result;
using params_t = std::tuple<Parameters...>;
virtual void operator()(Result& result, const Parameters&...) const = 0;
};
class MyField : public Superposable<double, double, double>
{
public:
void operator()(double& result, const double& p1, const double& p2) const
{
result = p1 + p2;
}
};
template <typename, typename>
class Superposition_impl;
template <typename S, std::size_t... Is>
class Superposition_impl<S, std::index_sequence<Is...>>
{
static_assert(std::is_base_of<Superposable<typename S::result_t, typename std::tuple_element<Is, typename S::params_t>::type...>, S>::value, "!");
public:
std::vector<std::shared_ptr<S>> elements;
void operator()(typename S::result_t& result, const typename std::tuple_element<Is, typename S::params_t>::type&... parameters) const
{
for (auto p : elements)
{
typename S::result_t r;
(*p)(r, parameters...);
result += r;
}
}
};
template <typename S>
using Superposition = Superposition_impl<S, std::make_index_sequence<std::tuple_size<typename S::params_t>::value>>;
DEMO

C++ Partial template specialization - design simplification

I am working on a pipeline/dataflow design pattern. I have a class 'algorithm data output' (AlgorithmOutput) that acts as an interface between two connected network segments. In particular, it provides method templates getOutput<size_t N> that are used for the data output from an object of the type 'data transmitter'.
The current design is based on the idea that users derive from the class AlgorithmOutput and provide a finite number of implementations of the method template getOutput<size_t N>. I also need to be able to allow users to provide their own custom return types from the method getOutput (i.e. the return type cannot be polymorphic). Moreover, it is necessary to have all implementations of getOutput to be able to access the same data set defined as a member of the class to which the methods belong.
The current solution uses partial explicit specialisation in the classes derived by the user to define the different implementations of the method getOutput. I would like to simplify the solution and would appreciate any ideas on how this can be done without losing the functionality of the current design.
EDIT: I am only concerned about the ease of implementation of the method getOutput from the perspective of the user. I am not concerned about how complex is the implementation of the base classes.
An example of the implementation of the derived class:
class PipeOutputClass: public AlgorithmOutput<PipeOutputClass>
{
public:
template <size_t N>
auto getOutput(size_t c_Idx) const
{
return getOutputImpl<N>::apply(this, c_Idx);
}
template<size_t N, typename S> friend struct getOutputImpl;
template<size_t N, typename = void>
struct getOutputImpl
{
static auto apply(
PipeOutputClass const* p_Self,
size_t c_Idx
)
{
throw std::runtime_error("Wrong template argument.");
}
};
template <typename S>
struct getOutputImpl<0, S>
{
static std::unique_ptr<double> apply(
PipeOutputClass const* p_Self,
size_t c_Idx
)
{
std::unique_ptr<double> mydouble(new double(10));
return mydouble;
}
};
template <typename S>
struct getOutputImpl<1, S>
{
static std::unique_ptr<int> apply(
PipeOutputClass const* p_Self,
size_t c_Idx
)
{
std::unique_ptr<int> myint(new int(3));
return myint;
}
};
};
You could use tag dispatching to avoid the need for partial specialization. A simplified version:
//we'll use this to overload functions based on a size_t template param
template <size_t N>
struct Size2Type{};
class PipeOutputClass
{
public:
template <size_t N>
auto getOutput(size_t c_Idx) const
{
//use Size2Type to tag dispatch
return getOutputImpl(Size2Type<N>{}, c_Idx);
}
//default version for when we don't explicitly provide an overload
template <size_t N>
auto getOutputImpl(Size2Type<N>, size_t c_Idx) const
{
throw std::runtime_error("Wrong template argument.");
}
//overload for when N = 0
std::unique_ptr<double> getOutputImpl (Size2Type<0>, size_t c_Idx) const
{
std::unique_ptr<double> mydouble(new double(10));
return mydouble;
}
//overload for when N = 1
std::unique_ptr<int> getOutputImpl (Size2Type<1>, size_t c_Idx) const
{
std::unique_ptr<int> myint(new int(3));
return myint;
}
};

C++ mixing strongly typed base class with CRTP and return value type deduction

I have some conceptual problem in a class hierarchy, where the Base class depends on a fixed scalar type T, but the derived CRTP'ed classes use return value type deduction.
For example, consider the following class hierarchy:
template<typename ... Args> struct VectorBase;
template<typename T>
struct VectorBase<T>
{
virtual T eval(int) const = 0;
auto operator[](int i) {return this->eval(i);}
};
template<typename T, typename Derived>
struct VectorBase<T, Derived> : public VectorBase<T>
{
virtual T eval(int i) const override final { return this->operator[](i); }
auto operator[](int i) const
{
return static_cast<Derived const&>(*this).operator[](i);
}
};
template<typename T>
struct Vector : public VectorBase<T, Vector<T> >
{
//just for code shortness,
//in reality there is a container which returns the corresponding elements
auto operator[](int i) const { return T{}; }
};
template<typename VectorType>
struct SomeTransformation : public VectorBase< /* ... what to write here generically? */ double, SomeTransformation<VectorType> >
{
VectorType const& v;
SomeTransformation(VectorType const& _v) : v(_v) {}
auto operator[](int i) const
{
//do something with vector v and return i-th element, e.g.
return v[i]*0.1;
}
};
DEMO
Now, given a specific vector with value type int, say, one can apply SomeTransformation and get a vector of value type double. Moreover, I can be sure that SomeTransformation derives from VectorBase<double>, so that, for example, I can't falsely assign it to a VectorBase<int>-pointer:
int main()
{
Vector<int> v;
std::cout<<typeid(decltype(v[0])).name()<<std::endl; //prints "i" for int
auto u = SomeTransformation<decltype(v)>(v);
std::cout<<typeid(decltype(u[0])).name()<<std::endl; //prints "d" for double
//works
std::unique_ptr<VectorBase<double> > ud = std::make_unique<SomeTransformation<decltype(v)> >(v);
//gives a compile-time error, which is good
//std::unique_ptr<VectorBase<int> > ui = std::make_unique<SomeTransformation<decltype(v)> >(v);
}
Now for the problem: in the scalar type argument of SomeTransformation, where I wrote /* ... what to write here generically? */, I really would want to write something like
template<typename VectorType>
struct SomeTransformation :
public VectorBase<decltype(std::declval<SomeTransformation<VectorType> >().operator[](0)), SomeTransformation<VectorType> >
{
//...
};
in order to deduce the value type of the transformation automatically and propagate this type down to the base class. However, this doesn't seem to work, which I think is because the base classes are instantiated before the derived class ... so the class of which I want to deduce the type doesn't exists yet.
Is there any way to obtain this behaviour without breaking the inheritance hierarchy?
I figured out a possible alternative by myself and want to bring it up for discussion.
One could for instance add a type parameter T also to the derived class and then use a dummy type in order to instantiate this class once. With this, it is possible to deduce the return type of the so-created class, which is used in a next step to instantiate the class to be really used.
Example:
namespace detail
{
template<typename T, typename VectorType>
struct SomeTransformation :
public VectorBase<T, SomeTransformation<T, VectorType> >
{
//the same as above
};
}
struct DummyType
{
//make any type convertible to DummyType
template<typename T> DummyType(T const&) {}
};
template<typename VectorType>
using SomeTransformationValueType =
decltype(std::declval<detail::SomeTransformation<DummyType, VectorType> >().operator[](0));
template<typename VectorType>
using SomeTransformation =
typename detail::SomeTransformation<SomeTransformationValueType<VectorType>, VectorType>;
DEMO

How to emulate EBO when using raw storage?

I have a component I use when implementing low-level generic types that store an object of arbitrary type (may or may not be a class type) which may be empty to take advantage of the empty base optimization:
template <typename T, unsigned Tag = 0, typename = void>
class ebo_storage {
T item;
public:
constexpr ebo_storage() = default;
template <
typename U,
typename = std::enable_if_t<
!std::is_same<ebo_storage, std::decay_t<U>>::value
>
> constexpr ebo_storage(U&& u)
noexcept(std::is_nothrow_constructible<T,U>::value) :
item(std::forward<U>(u)) {}
T& get() & noexcept { return item; }
constexpr const T& get() const& noexcept { return item; }
T&& get() && noexcept { return std::move(item); }
};
template <typename T, unsigned Tag>
class ebo_storage<
T, Tag, std::enable_if_t<std::is_class<T>::value>
> : private T {
public:
using T::T;
constexpr ebo_storage() = default;
constexpr ebo_storage(const T& t) : T(t) {}
constexpr ebo_storage(T&& t) : T(std::move(t)) {}
T& get() & noexcept { return *this; }
constexpr const T& get() const& noexcept { return *this; }
T&& get() && noexcept { return std::move(*this); }
};
template <typename T, typename U>
class compressed_pair : ebo_storage<T, 0>,
ebo_storage<U, 1> {
using first_t = ebo_storage<T, 0>;
using second_t = ebo_storage<U, 1>;
public:
T& first() { return first_t::get(); }
U& second() { return second_t::get(); }
// ...
};
template <typename, typename...> class tuple_;
template <std::size_t...Is, typename...Ts>
class tuple_<std::index_sequence<Is...>, Ts...> :
ebo_storage<Ts, Is>... {
// ...
};
template <typename...Ts>
using tuple = tuple_<std::index_sequence_for<Ts...>, Ts...>;
Lately I've been messing about with lock-free data structures and I need nodes that optionally contain a live datum. Once allocated, nodes live for the lifetime of the data structure but the contained datum is only alive while the node is active and not while the node sits in a free list. I implemented the nodes using raw storage and placement new:
template <typename T>
class raw_container {
alignas(T) unsigned char space_[sizeof(T)];
public:
T& data() noexcept {
return reinterpret_cast<T&>(space_);
}
template <typename...Args>
void construct(Args&&...args) {
::new(space_) T(std::forward<Args>(args)...);
}
void destruct() {
data().~T();
}
};
template <typename T>
struct list_node : public raw_container<T> {
std::atomic<list_node*> next_;
};
which is all fine and dandy, but wastes a pointer-sized chunk of memory per node when T is empty: one byte for raw_storage<T>::space_, and sizeof(std::atomic<list_node*>) - 1 bytes of padding for alignment. It would be nice to take advantage of EBO and allocate the unused single-byte representation of raw_container<T> atop list_node::next_.
My best attempt at creating a raw_ebo_storage performs "manual" EBO:
template <typename T, typename = void>
struct alignas(T) raw_ebo_storage_base {
unsigned char space_[sizeof(T)];
};
template <typename T>
struct alignas(T) raw_ebo_storage_base<
T, std::enable_if_t<std::is_empty<T>::value>
> {};
template <typename T>
class raw_ebo_storage : private raw_ebo_storage_base<T> {
public:
static_assert(std::is_standard_layout<raw_ebo_storage_base<T>>::value, "");
static_assert(alignof(raw_ebo_storage_base<T>) % alignof(T) == 0, "");
T& data() noexcept {
return *static_cast<T*>(static_cast<void*>(
static_cast<raw_ebo_storage_base<T>*>(this)
));
}
};
which has the desired effects:
template <typename T>
struct alignas(T) empty {};
static_assert(std::is_empty<raw_ebo_storage<empty<char>>>::value, "Good!");
static_assert(std::is_empty<raw_ebo_storage<empty<double>>>::value, "Good!");
template <typename T>
struct foo : raw_ebo_storage<empty<T>> { T c; };
static_assert(sizeof(foo<char>) == 1, "Good!");
static_assert(sizeof(foo<double>) == sizeof(double), "Good!");
but also some undesirable effects, I assume due to violation of strict aliasing (3.10/10) although the meaning of "access the stored value of an object" is debatable for an empty type:
struct bar : raw_ebo_storage<empty<char>> { empty<char> e; };
static_assert(sizeof(bar) == 2, "NOT good: bar::e and bar::raw_ebo_storage::data() "
"are distinct objects of the same type with the "
"same address.");
This solution also potential for undefined behavior upon construction. At some point the program must construct the containee object within the raw storage with placement new:
struct A : raw_ebo_storage<empty<char>> { int i; };
static_assert(sizeof(A) == sizeof(int), "");
A a;
a.value = 42;
::new(&a.get()) empty<char>{};
static_assert(sizeof(empty<char>) > 0, "");
Recall that despite being empty, a complete object necessarily has non-zero size. In other words, an empty complete object has a value representation that consists of one or more padding bytes. new constructs complete objects, so a conforming implementation could set those padding bytes to arbitrary values at construction instead of leaving memory untouched as would be the case for constructing an empty base subobject. This would of course be catastrophic if those padding bytes overlay other live objects.
So the question is, is it possible to create a standard-compliant container class that uses raw storage/delayed initialization for the contained object and takes advantage of EBO to avoid wasting memory space for the representation of the contained object?
I think you gave the answer yourself in your various observations:
You want raw memory and placement new. This requires to have at least one byte available, even if you want to construct an empty object via placement new.
You want zero bytes overhead for storing any empty objects.
These requirements are self-contradicting. The answer therefore is No, that is not possible.
You could change your requirements a bit more, though, by requiring the zero byte overhead only for empty, trivial types.
You could define a new class trait, e.g.
template <typename T>
struct constructor_and_destructor_are_empty : std::false_type
{
};
Then you specialize
template <typename T, typename = void>
class raw_container;
template <typename T>
class raw_container<
T,
std::enable_if_t<
std::is_empty<T>::value and
std::is_trivial<T>::value>>
{
public:
T& data() noexcept
{
return reinterpret_cast<T&>(*this);
}
void construct()
{
// do nothing
}
void destruct()
{
// do nothing
}
};
template <typename T>
struct list_node : public raw_container<T>
{
std::atomic<list_node*> next_;
};
Then use it like this:
using node = list_node<empty<char>>;
static_assert(sizeof(node) == sizeof(std::atomic<node*>), "Good");
Of course, you still have
struct bar : raw_container<empty<char>> { empty<char> e; };
static_assert(sizeof(bar) == 1, "Yes, two objects sharing an address");
But that is normal for EBO:
struct ebo1 : empty<char>, empty<usigned char> {};
static_assert(sizeof(ebo1) == 1, "Two object in one place");
struct ebo2 : empty<char> { char c; };
static_assert(sizeof(ebo2) == 1, "Two object in one place");
But as long as you always use construct and destruct and no placement new on &data(), you're golden.

"dual inheritance" pointer

So an A* pointer can point to any object having a base A, and a B* pointer can point to any object with a base B*. Is there anyway to make a pointer that can only point to objects that have both A and B as a base?
I'd also want it to be something I can store as a class member (perhaps a smart version) without making that class a template class.
Edit:
#KerrekSB asked below what the point of this is. Basically I want to make a number of pure virtual base classes (i.e. interfaces) say printable, flyable, something_else_able etc.
And then I might have a new class which requires in it's constructor requires something which is both printable and flyable. If it was just one or the other, you could store it as a (smart) pointer and let polymorphism take care of the rest, but I'm trying to work out how to do this if the class uses both bases.
Sure, you can use a type trait:
#include <type_traits>
template <typename T, typename A, typename B> struct has_two_bases
: std::integral_constant<bool, std::is_base_of<A, T>:: value &&
std::is_base_of<B, T>:: value> { }
Usage:
static_assert(has_two_bases<T, A, B>::value, "Not a good type");
T * p;
Does something like this fit the bill?
class W {};
class X {};
class Y {};
class Z : public X, public Y {};
template <typename A, typename B>
class DualPointer {
public:
template <typename T>
DualPointer(T *t) : a_ptr_(t), b_ptr_(t) {}
operator A*() { return a_ptr_; }
operator B*() { return b_ptr_; }
private:
A *a_ptr_;
B *b_ptr_;
};
int main() {
Z z;
DualPointer<X, Y> p(&z);
X *x = p;
Y *y = p;
return 0;
}
Or if you're in a C++11 mood:
template <typename... Ts>
class MultiPointer;
template <typename T, typename... Rest>
class MultiPointer<T, Rest...> : public MultiPointer<Rest...> {
public:
template <typename U>
MultiPointer(U *u) : MultiPointer<Rest...>(u), ptr_(u) {};
operator T*() { return ptr_; }
private:
T *ptr_;
};
template <>
class MultiPointer<> {
public:
MultiPointer(void *) {}
};
int main() {
Z z;
MultiPointer<X, Y> p(&z);
X *x = p;
Y *y = p;
return 0;
}
If you're worried about the double storage of pointers, this approach doesn't work. See comments below this answer as to why incorporating Paweł's suggestion of using a union, which works if and only if all the pointers are numerically identical (that is, there's no multiple inheritance or other shenanigans using adjusted this pointers going on), is unsafe and basically useless.
// DON'T USE THIS VARIANT!!!!
template <typename... Ts>
class MultiPointer {
public:
MultiPointer(void *) {}
};
template <typename T, typename... Rest>
class MultiPointer<T, Rest...> {
public:
template <typename U> MultiPointer(U *u) : rest_(u) { ptr_ = u; };
template <typename U> operator U*() const { return rest_; }
operator T*() const { return ptr_; }
private:
union {
T *ptr_;
MultiPointer<Rest...> rest_;
};
};
While you could write a pointer wrapper class (similar to "smart pointers", but not so smart in this case) which only accepts pointers to types derived from A and B, dereferencing them becomes ambiguous. This is a conceptual problem you can't solve with any method.
But you could provide two functions toA() and toB() and/or conversion operators in order to retrieve a pointer to one of the base classes. But as said, you can't (nicely) overload operator* to retrieve the base reference depending on the context (depending on whether an A* or a B* is needed in the context). Same with operator->.
template<typename A, typename B>
class DualPointer {
A *a; // We need two separate pointers because their distance is not known
B *b;
public:
template<typename T>
DualPointer(T* object) :
a(object),
b(object)
{ }
A *toA() const { return a; }
B *toB() const { return b; }
operator A* () const { return a; }
operator B* () const { return b; }
};
Using SFINAE you can also allow a function template which has the actual type as the template parameter, like to<MyBaseA>():
template<typename T>
typename std::enable_if<std::is_same<A, T>::value, T*>::type
to() {
return a;
}
template<typename T>
typename std::enable_if<std::is_same<B, T>::value, T*>::type
to() {
return b;
}
Demonstration of this wrapper class
You can then add such a pointer as a class member as requested in your question:
class MyClass {
DualPointer<MyBaseA, MyBaseB> pointer;
};
and access the pointer like:
pointer.toA()->memberFunctionOfA();
If your types A and B are fixed, then either drop the "template" line and replace A and B accordingly, or add a typedef DualPointer<MyBaseA, MyBaseB> MyAOrB;
Expanding on this, you could say one of the two base classes, say the first, is your "main" base class. That could then be the one the pointer acts like, so the one returned by operator* and operator->. The two operators would then look like:
A * operator-> () const { return a; }
A & operator* () const { return *a; }
Then the call from above can become as easy as
pointer->memberFunctionOfA();
but not simultaneously
pointer->memberFunctionOfB();