template <typename T, typename C>
class CSVWriter{
template <typename PrinterT>
void write(std::ostream& stream, const PrinterT& printer){
}
};
I want to check whether there exists at least two overloads PrinterT::operator()(T*) and PrinterT::operator()(C*)
PrinterT may or may not inherit from std::unary_function
What concept Checking Classes I need to use here ?
(I am not using C++11)
You can use something like that
#include <iostream>
#include <boost/concept/requires.hpp>
#include <boost/concept/usage.hpp>
template <class Type, class Param>
class has_operator_round_brackets_with_parameter
{
public:
BOOST_CONCEPT_USAGE(has_operator_round_brackets_with_parameter)
{
_t(_p);
}
private:
Type _t;
Param _p;
};
struct X {};
struct Y {};
struct Test1
{
void operator() (X*) const { }
};
struct Test2: public Test1
{
void operator() (X*) const { }
void operator() (Y*) const { }
};
template <class T, class C>
struct CSVWriter
{
template <class PrinterT>
BOOST_CONCEPT_REQUIRES(
((has_operator_round_brackets_with_parameter<PrinterT, T*>))
((has_operator_round_brackets_with_parameter<PrinterT, C*>)),
(void)) write(std::ostream& stream, const PrinterT& printer)
{
}
};
int main()
{
CSVWriter<X, Y> w;
// w.write<Test1>(std::cout, Test1()); // FAIL
w.write<Test2>(std::cout, Test2()); // OK
return 0;
}
Related
I want to do multiple inheritance via template arguments and pass reference to this in each base class, so I can call top level object's method from each base class's method. I can do it with manual inheritance, but I want to be able to do this via templates arguments.
Godbolt link
Godbolt link with manual inheritance
#include <cstdio>
template <typename T>
struct Foo {
Foo(T &t)
: t_(t) {
}
void foo() {
t_.call("foo");
}
T &t_;
};
template <typename T>
struct Bar {
Bar(T &t)
: t_(t) {
}
void bar() {
t_.call("bar");
}
T &t_;
};
template <template<typename> typename... Methods>
struct Impl : public Methods<Impl>... {
Impl()
: Methods<Impl>(*this)... {
}
void call(const char *m) {
printf(m);
}
};
int main() {
auto t = Impl<Foo, Bar>();
t.foo();
t.bar();
}
I tried this approach, but it gives
type/value mismatch at argument 1 in template parameter list for 'template<class> class ... Methods'
Thanks to #Nicol Bolas, he advised to use static_cast and CRTP for this
#include <cstdio>
template <typename T>
struct Foo {
void foo() {
static_cast<T*>(this)->call("foo");
}
};
template <typename T>
struct Bar {
void bar() {
static_cast<T*>(this)->call("bar");
}
};
template <template<typename> typename... Methods>
struct Impl : public Methods<Impl<Methods...>>... {
Impl() {
}
void call(const char *m) {
printf(m);
}
};
int main() {
auto t = Impl<Foo, Bar>();
t.foo();
t.bar();
}
I would like a class to have a function with a template argument, and based on that template argument a particular member variable is manipulated.
For example, if function template specialization were allowed, then something like this:
struct A
{
struct M1 {};
struct M2 {};
// Function template specialization not allowed :(
template<typename M>
void addM(M const &m);
template<>
void addM(M1 const &m)
{
m1_vec_.push_back(m);
}
template<>
void addM(M2 const &m)
{
m2_vec_.push_back(m);
}
std::vector<M1> m1_vec_;
std::vector<M2> m2_vec_;
};
Any ideas? I feel like I'm missing something simple but can't quite put my finger on it.
Just overload them :
struct A
{
struct M1 {};
struct M2 {};
void addM(M1 const &m)
{
m1_vec_.push_back(m);
}
void addM(M2 const &m)
{
m2_vec_.push_back(m);
}
std::vector<M1> m1_vec_;
std::vector<M2> m2_vec_;
};
If you do not wish to duplicate addM's code, you can just abstract the vector choice behind another function :
struct A
{
struct M1 {};
struct M2 {};
template <class T>
void addM(T const &m)
{
getVec<T>().push_back(m);
}
std::vector<M1> m1_vec_;
std::vector<M2> m2_vec_;
private:
template<class T>
std::vector<T> &getVec();
};
template <>
std::vector<A::M1> &A::getVec() { return m1_vec_; }
template <>
std::vector<A::M2> &A::getVec() { return m2_vec_; }
I got a BaseType which is templated and want to inheritance it with an ArrayItem class. Since i want to use them as stencil for memory i want the ArrayItem class to know which type we have. So i'd like to specialize the constructor for some of the Template values for example long long.
template<typename T>
class ArrayItem : public BaseType<T>
{
public:
inline ArrayItem(T& t);
inline ETypes getType();
private:
ETypes m_type;
};
And the hpp should look like this:
template <typename T>
ArrayItem<T>::ArrayItem (T& t): BaseType(t)
{
}
template <>
ArrayItem<long long>::ArrayItem(long long& t) : BaseType<long long>(t) // this
{
m_type = INT;
}
template<typename T>
inline ETypes ArrayItem<T>::getType()
{
return m_type;
}
But the how do i do this specialization here?
enum ETypes
{
INT,
BOOL,
OBJECT,
ARRAY,
DOUBLE,
STRING
};
template <typename T>
class BaseType
{
public:
BaseType();
explicit BaseType(T& t);
protected:
union DataUnion
{
T data;
size_t size; //to make it at least 64bit
explicit DataUnion(T& t);
} m_data;
};
template <typename T>
BaseType<T>::DataUnion::DataUnion(T& t)
{
this->data = t;
}
template <typename T>
BaseType<T>::BaseType(T& t) : m_data(t) {}
template<typename T>
class ArrayItem : public BaseType<T>
{
public:
explicit inline ArrayItem(T& t);
inline ETypes getType();
private:
ETypes m_type;
};
template <typename T>
ArrayItem<T>::ArrayItem (T& t): BaseType<T>(t)
{
}
template <>
ArrayItem<long long>::ArrayItem(long long& t) : BaseType<long long>(t) // this
{
m_type = INT;
}
template<typename T>
inline ETypes ArrayItem<T>::getType()
{
return m_type;
}
int main()
{
long long somenumber = 1234;
ArrayItem<long long> item(somenumber);
if(item.getType() == INT)
std::cout<< "inttype";
//after this we can stancil the ptr to a
//BaseType<long long> since we know it's a long here
}
What you have looks right to me, outside of not providing the template arguments to BaseType for the typical case.
Here's a simple demo:
#include <iostream>
template <typename T>
struct B { };
template <typename T>
struct D : B<T> {
D(T );
};
template <typename T>
D<T>::D(T )
: B<T>()
{
std::cout << "def\n";
}
template <>
D<long>::D(long )
: B<long>()
{
std::cout << "hi\n";
}
int main()
{
D<int> i(4); // prints def
D<long> l(5); // prints hi
}
I have a templated class with variable numbers of templated arguments. As in these cases (I cannot afford C++11) a good practice is to create a default class that we call none and put it as default like below.
struct none {};
template<class T1=none, T2=none, T3=none>
class A{
template<class T>
double extract() { return none();}
template<>
double extract<T1>() { return m1_();}
template<>
double extract<T2>() { return m2_();}
template<>
double extract<T3> () { return m3_();}
T1 m1_;
T2 m2_;
T3 m3_;
};
At this stage I don't know how to implement a generic/templated accessor function that can access each of the templated argument.
All of the templated arguments are different so I specialized A::extract() for each of the templated arguments.
Is there any better way to do this? Any sort of tagging I can have a look at?
struct none {};
template <class T, class N>
class Holder : public N
{
protected:
T m;
typedef Holder<T, N> First;
double extractP(T*) { return m(); }
template <class X> double extractP(X*) {
return this->N::extractP(static_cast<X*>(0));
}
};
template <class T>
class Holder<T, none>
{
protected:
T m;
typedef Holder<T, none> First;
double extractP(T*) { return m(); }
template <class X> none extractP(X*) {
return none();
}
};
template <class T1 = none, class T2 = none, class T3 = none>
class A : Holder<T1, Holder<T2, Holder<T3, none> > >
{
public:
template <class T> double extract() {
return this->extractP(static_cast<T*>(0));
}
};
A similarly-named solution to n.m but more on the Boost's Variant class design.
The suggestion is to use a Variant container (a generic container for your objects) and use accessors directly on them.
#include <iostream>
#include <stdexcept>
using namespace std;
class BaseHolder
{
public:
virtual ~BaseHolder(){}
virtual BaseHolder* clone() const = 0;
};
template<typename T>
class HoldData : public BaseHolder
{
public:
HoldData(const T& t_) : t(t_){}
virtual BaseHolder* clone() const {
return new HoldData<T>(t);
}
T getData() {
return t;
}
private:
T t;
};
class Variant
{
public:
Variant() : data(0) {}
template<typename T>
Variant(const T& t) : data(new HoldData<T>(t)){}
Variant(const Variant& other) : data(other.data ? other.data->clone() : 0) {}
~Variant(){delete data;}
template<typename T>
T getData() {
return ((HoldData<T>*)data)->getData();
}
private:
BaseHolder* data;
private:
Variant& operator=(const Variant& other) { return *this;} // Not allowed
};
struct none {};
class Container{
public:
Container() : m1_(0), m2_(0), m3_(0){}
~Container() {
if(m1_)
delete m1_;
if(m2_)
delete m1_;
if(m3_)
delete m1_;
}
none extract() { return none();}
template<typename T>
void insertM1(T obj) {
m1_ = new Variant(obj);
}
template<typename T>
T extractM1() {
if(m1_ != 0)
return m1_->getData<T>();
else
throw std::runtime_error("Element not set");
}
// TODO: implement m2 and m3
Variant *m1_;
Variant *m2_;
Variant *m3_;
};
int main() {
Container obj;
char M1 = 'Z';
obj.insertM1(M1);
char extractedM1 = obj.extractM1<char>();
cout << extractedM1;
return 0;
}
http://ideone.com/BaCWSV
Your class seems to mimic std::tuple, which, unfortunately for you, was added in C++11. The good news is that you can use boost::tuple instead.
As an example of usage:
boost::tuple<std::string, double> t = boost::make_tuple("John Doe", 4.815162342);
std::cout << boost::get<0>(t) << '\n';
std::cout << boost::get<1>(t) << '\n';
Live demo
Without access to C++11, it's a bit uglier, but you can leverage Boost.Tuple:
#include <iostream>
#include <boost/tuple/tuple.hpp>
template <size_t I, typename T, typename U>
struct AccessImpl;
template <size_t I, typename T, typename U>
struct AccessImpl {
template <typename Tuple>
static T& impl(Tuple& tuple) {
typedef typename ::boost::tuples::element<I+1, Tuple>::type Next;
return AccessImpl<I+1, T, Next>::impl(tuple);
}
};
template <size_t I, typename T>
struct AccessImpl<I, T, T> {
template <typename Tuple>
static T& impl(Tuple& tuple) { return boost::get<I>(tuple); }
};
template <typename T, typename Tuple>
T& access(Tuple& tuple) {
typedef typename ::boost::tuples::element<0, Tuple>::type Head;
return AccessImpl<0, T, Head>::impl(tuple);
}
int main() {
boost::tuples::tuple<char, int, std::string> example('a', 1, "Hello, World!");
std::cout << access<std::string>(example) << "\n";
return 0;
}
This, as expected, prints "Hello, World!".
template<typename T1, typename T2>
class Bimap {
public:
class Data {
private:
template<typename T> Data& set(T);
template<> Data& set<T1>(typename T1 v) { /*...*/ }
};
};
That gives me the error:
error: explicit specialization in non-namespace scope 'class Bimap<T1, T2>::Data'
I understand what the error is saying. But why I can't I do this? And how can I fix it?
One way forget templates, overload:
Data& set(T1 v) { /*...*/ }
but here is a trick which I use sometimes
you can specialize class template within class:
class {
template<typename T>
struct function_ {
static void apply(T);
};
template<>
struct function_<int> {
...
};
template<typename T>
void function(T t) { return function_<T>::apply(t); }
#Albert
I had a similar problem when I wanted to add a "trim-excess-capacity" to a custom made container. The std::vector swap trick and changing the declaration of the existing container were not valid options. So I've come up with this:
template <class T, bool isPtr> struct DeleteImp
{
static void Trim(T* to, unsigned int count);
};
template <class T> struct DeleteImp<T, false>
{
static void Trim(T* to, unsigned int count) {}
};
template <class T> struct DeleteImp<T, true>
{
static void Trim(T* to, unsigned int count)
{
for(unsigned int i=0; i<count; i++)
delete to[i];
}
};
used by my container like this:
DeleteImp<T, TypeTraits<T>::isPointer>::Trim(buf + length, truelength-length);
You may also want to check out this resource.