Variadic Template Template - c++

I am trying to create a base class that is a wrapper around std::array that overloads a bunch of common arithmetic operators. The end result will be sort of like std::valarray, but with static size. I'm doing this because I am creating a whole host of child classes for my library that end up replicating this functionality. For example, I need to create a MyPixel class and a MyPoint class, both of which are essentially just statically sized arrays that I can perform arithmetic on.
My solution is to create a StaticValArray base class from which MyPoint and MyPixel can derive. However to disallow users from adding a MyPoint to a MyPixel, I'm using the CRTP pattern as such:
template<class T1, class T2>
struct promote
{
typedef T1 type; // Assume there is a useful type promotion mechanism here
};
template<class T, size_t S, template<typename... A> class ChildClass>
class StaticValArray : public std::array<T,S>
{
public:
// Assume there are some conversion, etc. constructors here...
template<class U>
StaticValArray<typename promote<T,U>::type,S,ChildClass> operator+
(StaticValArray<U,S,ChildClass> const & rhs)
{
StaticValArray<typename promote<T,U>::type,S,ChildClass> ret = *this;
std::transform(this->begin(), this->end(),
rhs.begin(), ret.begin(), std::plus<typename promote<T,U>::type>());
return ret;
}
// More operators....
};
This is pretty cool, because the ChildClass can have any arbitrary class template parameters, and this thing will work. For example:
template<class T, class U>
class MyClassTwoTypes : public StaticValArray<T,3,MyClassTwoTypes>
{ };
template<class T, class U>
class MyClassTwoTypes2 : public StaticValArray<T,3,MyClassTwoTypes2>
{ };
int main()
{
MyClassTwoTypes<int, float> p;
MyClassTwoTypes<double, char> q;
auto z = p + q;
MyClassTwoTypes2<double, char> r;
// r += q; // <-- Great! This correctly won't compile
return 0;
}
My problem is this: I would like to stuff some ChildClass into the CRTP bit of StaticValArray that doesn't necessarily have just classes as its template parameters. For example, consider this N-Dimensional Point class:
template<class T, size_t S>
class MyPointND : public StaticValArray<T,S,MyPointND>
{ };
This unfortunately won't compile, because size_t is not a typename - I get the compiler error:
type/value mismatch at argument 3 in template parameter list for ‘template<class T, long unsigned int S, template<class ... A> class ChildClass> class StaticValArray’
test.C:36:54: error: expected a template of type ‘template<class ... A> class ChildClass’, got ‘template<class T, long unsigned int S> class MyPointND’
Is there any way to create a variadic template template parameter pack that can be absolutely anything (typenames, ints, size_t's, doubles, whatever?) because in the end I really don't care what the type is in there. Note that I can't just fully specify ChildClass (e.g. class MyPointND: public StaticValArray<T,S,MyPointND<T,S>>) because this would break my type promotion mechanism.

What if, in place of the size_t, you used an std::integral_constant? You would embed the numerical value of the size of your array in it, and you could use it as a type.
EDIT
In order to reduce the verbosity, you could define your own integral constant class, something like:
template <std::size_t N>
struct size_ : std::integral_constant<std::size_t,N> {};
Then you could use it like this:
MyPointND<int,size_<3>> x;

What you need to do is have a traits class, specialized for each type containing whatever you need for type promotion, and then pass in the complete type to the StaticValArray.
Moreover, with decltype, you shouldn't need anything like this- decltype will tell you what you get by adding a float and an int.
template<class U>
StaticValArray<decltype(*(T*)nullptr + *(U*)nullptr),S,ChildClass> operator+
(StaticValArray<U,S,ChildClass> const & rhs)
{
StaticValArray<decltype(*(T*)nullptr + *(U*)nullptr),S,ChildClass> ret = *this;
std::transform(this->begin(), this->end(),
rhs.begin(), ret.begin(), std::plus<decltype(*(T*)nullptr + *(U*)nullptr)>());
return ret;
}

Related

Factory method for template classes

I have an issue I'm facing where I'm trying to build a factory function that,
given an ID and a type will return the correct (templated) subclass.
What this is trying to solve:
The id() values are sent across a network as soon as a connection is established, and specify to the receiver how a sequence of bytes are encoded. The receiver knows in advance the type T that it expects, but does not know how that type T is encoded on the wire until it gets this value. It also specifies how return values (of some type U, where U may or may not be the same type as T) should be marshalled when they are returned. This code is used generally, i.e. there are multiple senders/receivers that use/expect different types; the types used between a given sender/receiver pair are always fixed, however.
A basic sketch of the problem: we have a (simplified) base class that defines id()
template <typename T>
class foo
{
public:
virtual ~foo() { }
// Other methods
// This must return the same value for every type T
virtual std::uint8_t id() const noexcept = 0;
};
From there, we have some subclasses:
template <typename T>
class bar : public foo<T>
{
public:
std::uint8_t id() const noexcept override { return 1; }
};
template <typename T>
class quux : public foo<T>
{
public:
std::uint8_t id() const noexcept override { return 2; }
};
For the actual factory function, I need to store something that
erases the type (e.g. bar, quux) so that I can store the actual
creation function in a homogenous container.
Effectively, I want semantics that are roughly equivalent to:
struct creation_holder
{
// Obviously this cannot work, as we cannot have virtual template functions
template <typename T>
virtual foo<T>* build() const;
};
template <template <typename> class F>
struct create : public creation_holder
{
// As above
template <typename T>
foo<T>* build() const override
{
return new F<T>();
}
};
std::unordered_map<std::uint8_t, create*>& mapping()
{
static std::unordered_map<std::uint8_t, create*> m;
return m;
}
template <typename T, template <typename> class F>
bool register_foo(F<T> foo_subclass,
typename std::enable_if<std::is_base_of<foo<T>, F<T>>::value>::type* = 0)
{
auto& m = mapping();
const auto id = foo_subclass.id();
creation_holder* hold = new create<F>();
// insert into map if it's not already present
}
template <typename T>
foo<T>* from_id(std::uint8_t id)
{
const auto& m = mapping();
auto it = m.find(id);
if(it == m.end()) { return nullptr; }
auto c = it->second;
return c->build<T>();
}
I've played around with a number of ideas to try and get something with similar
semantics, but with no luck. Is there a way to do this (I don't care if the
implementation is significantly different).
Some utility types for passing around types and bundles of types:
template<class...Ts>
struct types_t {};
template<class...Ts>
constexpr types_t<Ts...> types{}; // C++14. In C++11, replace types<T> with types_t<T>{}. Then again, I don't use it.
template<class T>
struct tag_t {};
template<class T>
constexpr tag_t<T> tag{}; // C++14. In C++11, replace tag<T> with tag_t<T>{} below
Now we write a poly ifactory.
Here is an ifactory:
template<template<class...>class Z, class T>
struct ifactory {
virtual std::unique_ptr<Z<T>> tagged_build(tag_t<T>) const = 0;
virtual ~ifactory() {}
};
you pass in the tag you want to build and you get out an object. Pretty simple.
We then bundle them up (this would be easier in c++171, but you asked for c++11):
template<template<class...>class Z, class Types>
struct poly_ifactory_impl;
The one type case:
template<template<class...>class Z, class T>
struct poly_ifactory_impl<Z,types_t<T>>:
ifactory<Z, T>
{
using ifactory<Z, T>::tagged_build;
};
the 2+ case:
template<template<class...>class Z, class T0, class T1, class...Ts>
struct poly_ifactory_impl<Z,types_t<T0, T1, Ts...>>:
ifactory<Z, T0>,
poly_ifactory_impl<Z, types_t<T1, Ts...>>
{
using ifactory<Z, T0>::tagged_build;
using poly_ifactory_impl<Z, types_t<T1, Ts...>>::tagged_build;
};
We import the tagged_build method down into the derived classes. This means that the most-derived poly_ifactory_impl has all of the tagged_build methods in the same overload set. We'll use this to dispatch to them.
Then we wrap it up pretty:
template<template<class...>class Z, class Types>
struct poly_ifactory:
poly_ifactory_impl<Z, Types>
{
template<class T>
std::unique_ptr<Z<T>> build() const {
return this->tagged_build(tag<T>);
}
};
notice I'm returning a unique_ptr; returing a raw T* from a factory method is code smell.
Someone with a poly_ifactory<?> just does a ->build<T>() and ignores the tagged_ overloads (unless they want them; I leave them exposed). Each tagged_build is virtual, but build<T> is not. This is how we emulate a virtual template function.
This handles the interface. At the other end we don't want to have to implement each build(tag_t<T>) manually. We can solve this with the CRTP.
template<class D, class Base, template<class...>class Z, class T>
struct factory_impl : Base {
virtual std::unique_ptr<Z<T>> tagged_build( tag_t<T> ) const override final {
return static_cast<D const*>(this)->build_impl( tag<T> );
}
using Base::build;
};
template<class D, class Base, template<class...>class Z, class Types>
struct poly_factory_impl;
the 1 type case:
template<class D, class Base, template<class...>class Z, class T0>
struct poly_factory_impl<D, Base, Z, types_t<T0>> :
factory_impl<D, Base, Z, T0>
{
using factory_impl<D, Base, Z, T0>::tagged_build;
};
the 2+ type case:
template<class D, class Base, template<class...>class Z, class T0, class T1, class...Ts>
struct poly_factory_impl<D, Base, Z, types_t<T0, T1, Ts...>> :
factory_impl<D, poly_factory_impl<D, Base, Z, types_t<T1, Ts...>>, Z, T0>
{
using factory_impl<D, poly_factory_impl<D, Base, Z, types_t<T1, Ts...>>, Z, T0>::tagged_build;
};
what this does is write a series of tagged_build(tag_t<T>) overloads of the ifactory methods, and redirects them to D::build_impl(tag_t<T>), where D is a theoretical derived type.
The fancy "pass Base around" exists to avoid having to use virtual inheritance. We inherit linearly, each step implementing one tagged_build(tag<T>) overload. All of them dispatch downward non-virtually using CRTP.
Use looks like:
struct bar {};
using my_types = types_t<int, double, bar>;
template<class T>
using vec = std::vector<T>;
using my_ifactory = poly_ifactory< vec, my_types >;
struct my_factory :
poly_factory_impl< my_factory, my_ifactory, vec, my_types >
{
template<class T>
std::unique_ptr< vec<T> > build_impl( tag_t<T> ) const {
return std::make_unique< std::vector<T> >( sizeof(T) );
// above is C++14; in C++11, use:
// return std::unique_ptr<vec<T>>( new vec<T>(sizeof(T)) );
}
};
and an instance of my_factory satisfies the my_ifactory interface.
In this case, we create a unique ptr to a vector of T with a number of elements equal to sizeof(T). It is just a toy.
Live example.
The pseudo code design.
The interface has a
template<class T> R build
function. It dispatches to
virtual R tagged_build(tag_t<T>) = 0;
methods.
The Ts in question are extracted from a types_t<Ts...> list. Only those types are supported.
On the implementation side, we create a linear inheritance of CRTP helpers. Each inherits from the last, and overrides a virtual R tagged_build(tag_t<T>).
The implementation of tagged_build uses CRTP to cast the this pointer to a more-derived class and call build_impl(tag<T>) on it. This is an example of non-runtime polymorphism.
So calls go build<T> to virtual tagged_build(tag_t<T>) to build_impl(tag<T>). Users just interact with one template; implementors just implement one template. The glue in the middle -- the virtual tagged_build -- is generated from a types_t list of types.
This is about 100 lines of "glue" or helper code, and in exchange we get effectively virtual template methods.
1 in c++17 this becomes:
template<template<class...>class Z, class...Ts>
struct poly_ifactory_impl<Z,types_t<Ts...>>:
ifactory<Z, Ts>...
{
using ifactory<Z, Ts>::tagged_build...;
};
which is much simpler and clearer.
Finally, you can do something vaguely like this without a central list of types. If you know both the caller and the callee know the type you could pass a typeid or typeindex into the ifactory, pass a void* or something similar out over the virtual dispatch mechanism, and cast/check for null/do a lookup in a map to types.
The internal implementation would look similar to this one, but you wouldn't have to publish types_t as part of your formal (or binary) interface.
Externally, you would have to "just know" what types are supported. At runtime, you might get a null smart (or dumb, ick) pointer out if you pass in an unsupported type.
With a bit of care you could even do both. Expose an efficient, safe mechanism to get compile-time known types applied to a template. Also expose a "try" based interface that both uses the efficient compile-time known system (if the type matches) and falls back on the inefficient runtime checked on. You might do this for esoteric backwards binary compatibility reasons (so new software can connect over an obsolete interface to new or old API implementations and handle having an old API implementation dynamically).
But at that point, have you considered using COM?

enable class's member depending on template

I already know that you can enable (or not) a class's method using std::enable_if
for exemple:
template<size_t D, size_t E>
class Field
{
...
size_t offset(const std::array<float,D>& p) const
{
...
}
template<typename TT = size_t>
typename std::enable_if<D!=E, TT>::type
offset(const std::array<float,E>& p) const
{
return offset(_projection(p));
}
...
};
This helps not being able to call function that are invalid in a specific case as well as removing overloading errors ... which, to me, is very nice !
I'd like to go further and make some of my class's members being present only if the are needed. That way I would get an error if I try to use an objected which would have otherwise not been initiated
I tried to do
template<size_t D, size_t E>
class Field
{
...
template<typename TT = projectionFunc>
typename std::enable_if<D!=E, TT>::type _projection;
}
But the compiler tells me :
erreur: data member ‘_projection’ cannot be a member template
Is there any way to achieve what I want ?
Hold the data members in a separate class that you can then specialize as needed.
template<size_t D, size_t E>
class Field {
template<size_t, size_t> struct Field_Members {
int _projection;
};
template<size_t V> struct Field_Members<V, V> { };
Field_Members<D, E> m;
};
and then use m._projection etc.
Field_Members doesn't have to be a nested class template; you can move it outside if desired. It is also possible to have Field inherit from it, but then it'd be a dependent base, and you'd have to write this->_projection, so it doesn't save much typing.
AFAIK, this is not possible with a simple SFINAE inside the class template. You can, of course, have the type of the member dependent on a compile-time condition, i.e. via std::conditional, but not eliminate the member entirely.
What you can do, of course, is use another class template, such as
template<bool Condition, typename T> struct Has { T value; };
template<typename T> struct Has<false,T> {};
and declare a member (or base) of this type and access the object via Has<>::value:
typename<bool Condition>
class foo
{
Has<Condition, double> x; // use x.value (only if Condition==true)
};

variadic templates same number of function arguments as in class

How to define method signature so it will accept same number of arguments as variadic template class definition? For example how to define an Array class:
template<typename T, int... shape>
class Array
{
public:
T& operator () (???);
};
So you will be able to call it like this:
Array<int, 3, 4, 5> a;
a(1, 2, 3) = 2;
template<class T, int...Shape>
class Array {
template<int>using index_t=int; // can change this
public:
T& operator()(index_t<Shape>... is);
};
or:
template<class T, int...Shape>
class Array {
public:
T& operator()(decltype(Shape)... is);
};
or:
template<class T, int...Shape>
class Array {
public:
T& operator()(decltype(Shape, int())... is);
};
if you want to be able to change the type of the parameter to be different than Shape.
I find the decltype harder to understand a touch than the using, especially if you want to change the type of the parameter to be different than int.
Another approach:
template<class T, int...Shape>
class Array {
public:
template<class...Args,class=typename std::enable_if<sizeof...(Args)==sizeof...(Shape)>::type>
T& operator()(Args&&... is);
};
which uses SFINAE. It does not enforce that the Args are integer types however. We could add another clause if we wanted to (that all of the Args are convertible to int, say).
Yet another approach is to have your operator() take a package of values, like a std::array<sizeof...(Shape), int>. Callers would have to:
Array<double, 3,2,1> arr;
arr({0,0,0});
use a set of {}s.
A final approach would be:
template<class T, int...Shape>
class Array {
public:
template<class...Args>
auto operator()(Args&&... is) {
static_assert( sizeof...(Args)==sizeof...(Shapes), "wrong number of array indexes" );
}
};
where we accept anything, then generate errors if it is the wrong number of arguments. This generates very clean errors, but does not do proper SFINAE operator overloading.
I would recommend tag dispatching, but I don't see a way to make it much cleaner than the SFINAE solution, with the extra decltype and all, or better error messages than the static_assert version on the other hand.
I assume you want your arguments to be all of the same type, probably using an integer type (I'll just use int). An easy approach is to leverage the parameter pack you already have:
template <int>
struct shape_helper { typedef int type; };
template <typename T, int... Shape>
class Array
{
public:
T& operator()(typename shape_helper<Shape>::type...);
};

Limit a templated function to base and derived types?

I have a template base class like this:
template<typename T, std::size_t Size>
class VectorT
{
public:
typedef T data_type;
}
and a few specialised derived classes:
template<typename T>
class Vector2d : public VectorT<T, 2U>
{ // some specialised functions }
template<typename T>
class Vector3d : public VectorT<T, 3U>
{ // some other specialised functions }
and these work fine. Howerver, I have a few free-standing functions for operators. For example:
template<typename T, size_t Size>
VectorT<T, Size> operator*(T lhs, const VectorT<T, Size>& rhs)
{
...
}
Unfortunately these do not work for my derived classes, because they return a VectorT<T, Size> instead of a Vector2d<T>.
So I tried with
template<V>
V operator*(typename V::data_type lhs, const V& rhs)
{
...
}
and this works fine, however it can lead to ambiguities because it sucks in anything else with a data_type member.
How can I get around this: how can I write type safe functions that only work with my vector base, or any derivatives of?
I am trying to get around having to re-declare and redefine the operators again for the subclasses.
You could add yet another base class, one that is independent of the template parameters, and use SFINAE to disable calls for types other than derived from such base:
struct VectorBase {};
template< typename T, std::size_t Size >
class VectorT : public VectorBase { ... }
template< typename V >
typename boost::enable_if< boost::is_base_of< VectorBase, V >, V >::type
operator*( V lhs, V const& rhs ){ ... }
Note that is_base_of< X, X > is always true, so this function will work for one more type than required, namely the base class VectorBase.
If you are using a compiler that implements TR1, you can replace boost:: for std:: in both places where is used.
You are in an unusual situation out of which there is no "nice" way. You can:
Check the type at runtime (or compile time, boost can probably do that)
Take a VectorT<>& and use that instead of creating a new VectorT inside the function and returning it. This way you can take subclasses of VectorT by reference as well. That would make you have to use a function instead of an operator though.
Do what K-ballo said.

How can I pass an arithmetic operator to a template?

I want to somehow merge templates like these into one:
template <class Result, class T1, class T2>
class StupidAdd
{
public:
T1 _a; T2 _b;
StupidAdd(T1 a, T2 b):_a(a),_b(b) {}
Result operator()() { return _a+_b; }
};
template <class Result, class T1, class T2>
class StupidSub
{
public:
T1 _a; T2 _b;
StupidSub(T1 a, T2 b):_a(a),_b(b) {}
Result operator()() { return _a-_b; }
};
(followed by the same code for Mul, Div, etc) where all the code is the same,
except for the actual "+", "-" (and "StupidAdd", "StupidSub", etc).
These Stupid "functors" are then used by another template.
How can I avoid the repetition, WITHOUT the preprocessor?
(The reason I got into templates was to avoid the preprocessor)
That is, how can I pass arithmetic operators into a template?
Maybe you could use std::plus<T>, std::minus<T>, std::multiplies<T> and std::divides<T>. However, these will work only if both operands are of the same type, or probably if the left one can be converted to the type of the first one.
I don't see any way to achieve what you're trying to do, except by using the preprocessor. Any good reasons for not wanting macros ?
If you want to make sure the return type is large enough to contains the result, you could do something along this way:
#include <functional>
#include <boost/mpl/if_.hpp>
// Metafunction returning the largest type between T and U
// Might already exist in Boost but I can't find it right now...maybe
// boost::math::tools::promote_args
template <typename T, typename U>
struct largest :
boost::mpl::if_<
boost::mpl::bool_<(sizeof(T) > sizeof(U))>,
T,
U
>
{};
template <typename T, typename U, template <typename S> class Op>
struct Foo
{
typedef typename largest<T, U>::type largeType;
largeType bar(const T & t, const U & u)
{
return Op<largeType>()(t, u); // Applies operator+
}
};
int main()
{
Foo<int, double, std::plus> f;
double d = f.bar(12, 13.0); // takes int and double, returns double
}
Here, I used Boost MPL to write the largest metafunction, but you could write your own if metafunction if you cannot use Boost (class template parameterized by two types and a bool, specialized for true and false).
To determine the return type of an expression, you could also have a look at boost::result_of which, if I understand correctly, is equivalent to the upcoming decltype operator in C++0x.
Thanks Luc, this is very cool.
I finally did it in a simpler way:
#include <functional>
template <
class Result,
class T1,
class T2,
template <class ReturnType> class BinaryOp>
class Stupido
{
public:
T1 _a; T2 _b;
Stupido(T1 a, T2 b):_a(a),_b(b) {}
Result operator()() { return BinaryOp<Result>()((Result)_a,(Result)_b); }
};
And used the "plus", "minus" when instantiating Stupido.
The cast to "Result" was enough for my needs (int + double => double + double => double)
I think there's an improvement to OldCoder's solution:
#include <functional>
template <class Result,
template <class Result> class BinaryOp>
struct Stupido
{
template <typename T1, typename T2>
Result operator()(const T1& a, const T2& b) { return BinaryOp<Result>()((Result)a,(Result)b); }
};
This way the call can be made as:
Stupido<int, std::plus > stup;
int result = stup(3.0f, 2.0);
and the same function object can be used with multiple operands, so it could be passed in to a std::transform call.
I believe there must be a way to remove one Result from the template declaration, but I am unable to find it.
I'd use the C++ 0x decltype and the new definition of auto. You'll still need to define the classes, but using these, you can do a nicer job of defining them. They'll still be about as much work to define, but at least using them will be considerably cleaner. In particular, you can use decltype/auto to deduce the correct return type instead of having to specify it explicitly.
These are available with a fair number of recent compilers -- Intel C++, g++, Comeau, the beta of VC++ 2010, and even the most recent iteration of Borland/Inprise/Embarcadero/this week's new name.