I have a pair of class template declarations like this:
template<typename T, template<typename W> class X>
struct B {
bool operator()(const T& left, const T& right)
{ return X<W>()(left, right); }
};
template<template<typename T> class X, typename Q>
struct A {
bool operator()(const int a, const int b)
{
return B<Q, X>()(a, b);
}
};
I can create A<std::greater, int>, A<std::less, int> and it works as I want.
Is it possible to create a class that will contain a template passed in like std::greater and still be able to be passed like std::greater itself in the example above?
Something like this:
template <template <typename T> class Class>
class Wrapper
{
operator()(const int, const int) { return Class<?what's here?> (value, value); }
};
I would like to pass my Wrapper to an unchanged A
A<Wrapper<std::less>, long>
In other words, I want to imitate a template passed to my wrapper, to be compatible with actual version of class A.
The short answer is no, not quite like you want it to be. The first argument of A must be a template name. But when you add arguments and write Wrapper<std::less>, you get a class type. It is no longer a template. Think of it this way, A expects a cookie cutter, but you pass a cookie made from the cutter instead.
That's not to say you can't turn a template into another template, but it won't be quite so opaque. The solution is to add a member template to Wrapper. Then Wrapper<std::less>, despite being a class type, will have a member that is a template. And you can pass that in to A.
template <template <typename T> class Class>
struct Wrapper
{
template<typename U> // member template
struct temp {
bool operator()(const int v1, const int v2)
{ return Class<U>()(v1, v2); }
};
};
This enables you to write A<Wrapper<std::less>::temp, long>.
Check it out live.
Related
Why the second function can't match the template in the class definition??
Class C {
template <typename T, typename T2 = T>
T val() const;
};
template <>
std::string C::val() const {
//OK
}
template <typename T, typename std::enable_if<std::is_arithmetic<T>::value>::type>
T C::val() const {
//Not OK
}
EDIT:
This is an overview of what I want to achieve. Basically I'm writing a function to parse and return an object based on the template type. I have some defined classes of my own, that is I have to parse with respect to their members. I also need to parse numerical types and to strings. So I wrote a specialized version for every of my defined classes. A version that parses to numerical types and return the given type (of course I have to make sure that the given type is numerical, hence the enable if)
To utilize SFINAE, use it in the template declaration, not specialization:
class C {
template <typename T, typename T2 = typename std::enable_if<std::is_arithmetic<T>::value>::type>
T val() const;
};
If you want to differentiate between arithemtic and non-arithmetic types (allowing both), you can utilize tagging:
class C {
public:
struct arithmetic_tag {};
struct non_arithmetic_tag {};
template <typename T>
T val(typename std::conditional<std::is_arithmetic<T>::value, arithmetic_tag, non_arithmetic_tag>::type tag = {}) const
{
return get_val<T>(tag);
}
private:
template <typename T>
T get_val(C::non_arithmetic_tag) const;
template <typename T>
T get_val(C::arithmetic_tag) const;
};
Or delegate the specialization to a helper class:
class C {
public:
template <typename T>
T val() const
{
return ValGetter<T>::get(this);
}
private:
template <typename T, bool is_arithmetic = std::is_arithmetic<T>::value>
struct ValGetter;
};
// Arithmetic
template <typename T>
struct C::ValGetter<T, true>
{
static T get(C const* c);
};
// Non-arithmetic
template <typename T>
struct C::ValGetter<T, false>
{
static T get(C const* c);
};
EDIT: partial specializations (bool parameter) do not work for methods, shown tagging and helper classes instead
I want to create a template class for generic operators. The class will have two structs representing a value as input:
struct Value {
DataType type;
size_t dataSize;
char* data;
};
I already have written a type deduction with oldschool switch-cases. After a cast of the data-ptr to the type, I want to apply an operation on the input values like this:
template<class Operation>
class ApplyOperation {
Value* operator()(const Value* a, const Value* b) const {
//find type of a and b
//cast a and b to their types
Operation<aT,bT> op;
return op(a,b);
}
};
Now I could write for each operation a little struct like this:
template<class A, class B>
struct Add {
A operator()(A a, B b) const { return a + b; }
};
I have seen a boost class called operators: http://www.boost.org/doc/libs/1_59_0/libs/utility/operators.htm
which I want to use for my purpose. But I don't know how to integrate it since the operators in the structs are no functors. So would it be possible to use it like this?:
ApplyOperation<boost::addable::operator+> add;
add(a,b);
Actually I'm trying it for testing with this class:
template<template<class T, class U, class...> class OperatorClass,class F>
struct ApplyOperator {
template<class T, class U>
T foo(T a, U b) {
OperatorClass<T,U> opClass;
return opClass.operator+(a,b); //this works of course
}
};
What I want to get is this:
template<template<class T, class U, class...> class OperatorClass,class F>
struct ApplyOperator {
template<class T, class U>
T foo(T a, U b) {
OperatorClass<T,U> opClass;
return opClass.F(a,b);
}
};
Instantiated like that:
ApplyOperation<boost::addable, operator+> add;
This doesn't work of course because of the unknown type operator+. So how can I call the operator+-function with templates?
Is there a way to get this solved?
I am not sure I fully understood the question. But it looks like you are trying to provide an object instance (not type) to your template ApplyOperator. Since operator+ is definitely not a type and not an integral constant, it can not be used as a template argument in no way. What you will have to do is to make an operation an argument to the constructor, not the type of the object.
Tag dispatch is mentioned in Switch passed type from template.
Is it possible (and how if it is) to do something like:
struct Tag1 {};
struct Tag2 {};
template<class T, typename R>
R get();
template<>
double get<Tag1>() {return 1.3;}
template<>
char const *get<Tag2>() {return "hello";}
double aDouble = get<Tag1>();
char const *aString = get<Tag2>();
The above code causes the complier to complain about ambiguous call to overloaded function, but I hope the last two lines communicate the intention of usage.
Thx
You could use std::enable_if and std::is_same (C++11), or their boost equivalents:
template <typename Tag>
typename std::enable_if<std::is_same<Tag, Tag1>::value, double>::type get()
{ ... }
template <typename Tag>
typename std::enable_if<std::is_same<Tag, Tag2>::value, char const *>::type get()
{ ... }
Function templates with different number of template parameters overload each others, so you aren't defining specialization but overload. Something like this should work:
struct Tag1 {};
struct Tag2 {};
template<class T> struct MapResult;
template<> struct MapResult<Tag1> { typedef double Result; };
template<> struct MapResult<Tag2> { typedef char const* Result; };
template<class T>
typename MapResult<T>::Result get();
template<> double get<Tag1>() {return 1.2;}
template<> char const *get<Tag2>() {return "hello";}
The second template parameter of get cannot be deduced because it only appears as the return type: who's to say that get<Tag1>() is a call to get<Tag1, double> specifically and not e.g. get<Tag1, int>? If you were to call e.g. get<Tag1, double>() then the call would be resolved to the correct specialization.
However I suspect that you don't really want get to be a function template with two template parameters: the return type is perhaps intended to be a function of the first parameter. As such, I suggest you declare get like so:
namespace result_of {
template<typename T>
struct get;
}
template<typename T>
typename result_of::get<T>::type get();
where result_of::get is going to be the metafunction that computes the expected result type. To make things simpler, rather than specializing the function template get we're going to put all our eggs in the result_of::get basket:
namespace result_of {
template<typename T>
struct get;
}
template<typename T>
typename result_of::get<T>::type get()
{ return result_of::get<T>::apply(); }
namespace result_of {
template<>
struct get<Tag1> {
typedef double type;
static type apply()
{ return 1.3; }
};
template<>
struct get<Tag2> {
typedef const char* type;
static type apply()
{ return "hello"; }
};
}
In general it's much more common to specialize class templates rather than function templates, and cases where it looks like it is needed to specialize a function template are often made simpler by letting the function template delegate its implementation entirely to a class template.
I'm trying to use templates with multiple to pass data onto a function, but using only the first template argument as a filter. Something like this:
template <typename A, typename B>
class Component {
};
template <typename A>
class Context {
public:
void add(Component<A, void *> comp) {
}
}
typedef struct Foo { int x; } Foo;
typedef struct Bar { int y; } Bar;
Context<Foo> *context = new Context<Foo>();
Component<Foo, Bar> *comp = new Component<Foo, Bar>();
context->add(comp); // error
But the compiler complains that it cannot convert Component<Foo, Bar> to Component<Foo, void *>. Is there a way to accomplish this?
I think what you probably need to do is change the signature of the 'add' method:
template <typename A>
class Context
{
public:
template<class B>
void add(Component<A, B> comp)
{
}
};
However, I don't know the details of your problem so this is a mere guess.
I'm trying to use templates with multiple to pass data onto a function, but using only the first template argument as a filter. [...] But the compiler complains that it cannot convert Component to Component. Is there a way to accomplish this?
Well, your filter works doesn't it: your add function will only match a Component whose second template parameter is void*, and you're providing Bar. What else could you possibly expect? If you want it to handle other "second-parameters" as well, either remove the filter, provide an fallback function for it to match, or some kind of conversion.
Yes, add a converting copy constructor to your Component:
template<class U, class V>
Component(Component<U,V> const& other){
// ...
};
But that is still refineable with the appropriate enable_if SFINAE guard:
// <tr1/type_traits> for C++03
#include <type_traits> // for C++0x
template<class T, class U>
struct can_convert{
// std::tr1::... for C++03
static bool const value =
std::is_same<T,U>::value || std::is_convertible<T,U>::value;
};
template<class C1, class C2>
struct ice_and{
static bool const value = C1::value && C2::value;
}
// define for clarity and brevity
#define IF_CAN_CONVERT(A,B,U,V) \
typename std::enable_if<ice_and<can_convert<A,U>,can_convert<B,V> > >::type* = 0
template<class U, class V>
Component(Component<U,V> const& other, IF_CAN_CONVERT(A,B,U,V)){
// ...
};
I already asked two questions related to what I'm trying to do (one resolved, one of which I will close soon). I know that C++ template instantiation does not allow any implicit conversions (see for example this comment), but I would like to simulate it.
Suppose I have the following skeleton code:
template <class T>
struct Base_A{
virtual void interface_func() const = 0;
};
template <class T>
struct Derived_A : public Base_A<T>{
typedef T value_type;
void interface_func() const{}
};
template <class T>
struct Base_B{
virtual void interface_func() = 0; // note: non-const
};
template <class T>
struct Derived_B : public Base_B<T>{
typedef T value_type;
void interface_func(){}
};
template <class BType>
struct Adapter : public Base_A<typename BType::value_type>{
BType &ref_B;
Adapter(BType &inst_B):ref_B(B_inst){}
void interface_func() const{} // does stuff with ref_B to simulate an A
};
template <class Should_Always_Be_Base_A>
void f(const Should_Always_Be_Base_A &arg){
// Only Base_A can be passed in by const ref
// Passing in a Base_B by const ref would not work.
}
Derived_A<int> A;
Derived_B<int> B;
f(A); // passes in A by const ref
f(B); // I want to pass in Adapter<Derived_B<int> >(B)
I want the template parameter for function f to always be a derived class of Base_A or an Adapter. The answer to restricting the type of arg can be done, but the implicit conversion to an Adapter cannot. Is there any way to do this? The net result is I want to be able to call f as f(A) or f(B), and in both cases I need to know the actual derived type of A or B within f (f cannot just see a reference to the base class).
Aside:
Presently, I just have f(A) working, and f(B) actually calls an overload which performs the Adapter construction, but I have other functions which take N arguments, each of which can be A or B, so I would need 2^N overloads.
For the curious, this is in application to the matrix library I'm working on. Base_A represents the base matrix type, and Base_B represents the base matrix-view type. For operations which will modify a matrix argument, I need to pass in the matrix by non-const reference or a modifiable matrix-view by const-ref. The adapter is just a trivial matrix-to-view adapter. So for example, I currently have a function like
Scale(const MatrixViewBase<T> &Mview, const T &scale_factor){
// does the actual work
}
Scale(MatrixBase<T> &M, const T &scale_factor){
Scale(Adapter<MatrixBase<T> >(M), scale_factor);
}
It's tedious and error prone to make 2^N copies of all these functions just to create the needed overloads to handle both views and non-views. As is, this is not good enough since I want Scale to be able to know the full derived type of Mview, not just the base class, because I will potentially generate instances of types dependent on Mview.
Edit 1: Changed all B types to have non-const interface functions. This was the original intent, so apologies for any confusion.
Edit 2: Have this working code, still requires 2^N overloads, but I can live with it unless someone suggests how to deal with that.
#include <iostream>
template <class T>
struct ReadableMatrix{
typedef T value_type;
};
template <class T>
struct WritableMatrix{
typedef T value_type;
};
template <class T>
struct WritableMatrixView{
typedef T value_type;
};
template <class T>
struct Matrix : public WritableMatrix<T>{
typedef T value_type;
typedef ReadableMatrix<T> readable_matrix;
typedef WritableMatrix<T> writable_matrix;
};
template <class T>
struct MatrixView : public WritableMatrixView<T>{
typedef T value_type;
typedef ReadableMatrix<T> readable_matrix; // not really used; needs an adapter before using
typedef WritableMatrixView<T> writable_matrix;
};
template <class T, class R>
struct IsReadableMatrix{
};
template <class T, class R>
struct IsReadableMatrix<ReadableMatrix<T>, R>{
typedef R type;
};
template <class T, class R>
struct IsWritableMatrix{
};
template <class T, class R>
struct IsWritableMatrix<WritableMatrix<T>, R>{
typedef R type;
};
template <class T, class R>
struct IsWritableMatrixView{
};
template <class T, class R>
struct IsWritableMatrixView<WritableMatrixView<T>, R>{
typedef R type;
};
template <class TA, class TB>
typename IsReadableMatrix<typename TA::readable_matrix,
typename IsWritableMatrixView<typename TB::writable_matrix,
void
>::type>::type
Copy(const TA &A, const TB &B){
std::cout << "Here" << std::endl;
}
template <class TA, class TB>
typename IsReadableMatrix<typename TA::readable_matrix,
typename IsWritableMatrix<typename TB::writable_matrix,
void
>::type>::type
Copy(const TA &A, TB &B){
std::cout << "Here2" << std::endl;
}
int main(){
Matrix<int> M, M2;
MatrixView<int> V, V2;
Copy(M, M2);
Copy(V, V2);
Copy(M, V);
Copy(V, M);
}
Do you need you base classes to be templates? Can you inject even "more base" nontemplate class?
If yes, you can do something like that:
struct Base_A{
virtual void interface_func() const = 0;
};
template <class T>
struct Derived_A : public Base_A{
typedef T value_type;
void interface_func() const{}
};
struct Base_B{
virtual void interface_func() const = 0;
};
template <class T>
struct Derived_B : public Base_B{
typedef T value_type;
void interface_func() const{}
};
struct Adapter
{
const Base_A* pA;
const Base_B* pB;
Adapter(const Base_B &inst_B) : pB(&inst_B), pA(0){}
Adapter(const Base_A &inst_A) : pA(&inst_A), pB(0){}
void interface_func() const
{
if( 0 != pA )
pA->interface_func();
else if( 0 != pB )
pB->interface_func();
}
};
void f(const Adapter &arg)
{
arg.interface_func(); // will call proper interface_func
}
int main()
{
Derived_A<int> A;
Derived_B<int> B;
f(A);
f(B);
}
Try the following:
template <template <typename> View, typename T>
struct Adapter
{
// Leave empty to cause errors if used, or you could
// provide a generic adapter for View<typename T::value_type>
}
// Partial specialization for a given base.
template <typename T>
struct Adapter<MatrixView, T> : MatrixView<typename T::value_type>
{
const T& t;
Adapter (const T& t)
: t(t)
{}
void some_virtual()
{
// Do stuff
}
}
template <template <typename> View, typename T>
const View<T>& adapt (const View<T>& v)
{
return v;
}
template <template <typename> View, typename T>
View<T> adapt (const T& t)
{
return Adapter<View, T>(t);
}
template <typename T, typename U>
foo(const MatrixViewBase<T> &Mview, const MatrixViewBase<U> &Mview2);
template <typename T, typename U>
foo (const T& t, const U& u)
{
return foo(adapt<MatrixViewBase>(t), adapt<MatrixViewBase>(u));
}
I put const in everywhere I could; you don't have to use it in every situation if it's not appropriate. You can use specializations of Adapter for a given T to further tailor the behavior.
Interestingly enough, this is the first time I've ever recommended template template parameters.
I have not looked into the details of a templated solution, but while you are at it, you can check the boost preprocessor library to help you in defining the 2^N variations of the template. This won't be nice on compile time, but it will be better than manually creating the variations.
I had to do this a while ago and the easiest (to maintain) solution I came up with was to have only one class (Matrix) that knows if it owns it's own data or is a view of someone else's data. E.g.,
Matrix A(n,m); //Creates a new matrix of size (n,m)
Matrix B=View(A); //Creates a matrix that's a view into A
Matrix C=View(pData,n,m); //Creates a matrix thats a view of data in a pointer that someone else owns
Foo(A);
Foo(B);
Foo(C);
It makes writing the Matrix class a little more difficult, but then later anyone who uses a Matrix, just uses it as a matrix, they don't need to care if it's a view or not.
Edited to add:
Why not just let BLAS manage the transpose for you? In the end, any of the BLAS functions are just going to want a pointer to a contiguous chunk of memory. So as long as your Matrix class knows how to get to that memory you're good. If the Matrix class has it's own isTransposed flag inside then you can do something like this:
Matrix A(n,m);
Matrix B=TransposedView(pData,m,n);
Matrix C=A*B;
Matrix& operator*(const Matrix& lhs, const Matrix& rhs)
{
Matrix result(lhs.Rows(),rhs.Cols()); //or did i get that backwards :)
char TransL=lhs.IsTransposed()?'T':'N';
char TransR=rhs.IsTransposed()?'T':'N';
_dgemm(TransL, TransR, ..., lhs.Data(), ..., rhs.Data(), ..., result.Data());
return result
}