Considering this following code :
class A
{
public:
void aFoo() {}
};
class B
{
public:
void bFoo() {}
};
class C
{
public:
void c1Foo() {}
void c2Foo() {}
};
Regardless the code architecture, is it possible to create a vector of pointers to member functions even if those functions are in multiple classes ?
In this case, inheritance is not a solution because we don't know how many functions we want to use in a class (class C has two functions). But we know they all have the same prototype.
Member functions of different classes have different types. So in order to have any homogeneous container (like std::vector or std::array) of those you'll need to wrap them in some value type that may represent them all (like boost::variant or boost::any).
On the other hand if all you need are member functions of a specific type (for example void()) and you don't mind passing the object on which they should be called before hand, then you can just store them as std::function<void()> (for this specific example) and just call std::bind on them before storing them in the container.
As an example, given:
A a; B b; C c;
std::vector<std::function<void()>> vector {
std::bind(&A::aFoo, a),
std::bind(&B::bFoo, b),
std::bind(&C::c1Foo, c),
std::bind(&C::c2Foo, c)
};
you would be able to call:
for (auto fn : vector)
fn();
Live demo
I am not sure what you want to achieve so this may not be very helpful but here it is anyway.
As others have said you cannot create a std::vector for this as the prototypes are different. You can however create a std::tuple like this:
std::tuple<void (A::*)(), void (B::*)(), void (C::*)()> x(&A::aFoo, &B::bFoo, &C::c1Foo);
Assuming you have a an instance of a class, say A a then you can call the function as in (a.*std::get<0>(x))().
If you have stored your objects in a tuple as well, then you can iterate over them. The following code will do just that (assumes you have C++14 and Boost in your system)
#include <iostream>
#include <tuple>
#include <type_traits>
#include <boost/mpl/find_if.hpp>
#include <boost/mpl/deref.hpp>
#include <boost/fusion/include/mpl.hpp>
#include <boost/fusion/adapted/std_tuple.hpp>
#include <boost/fusion/include/for_each.hpp>
#include <functional>
class A
{
public:
void aFoo()
{
std::cout << "A" << std::endl;
}
};
class B
{
public:
void bFoo()
{
std::cout << "B" << std::endl;
}
};
class C
{
public:
void c1Foo()
{
std::cout << "C1" << std::endl;
}
void c2Foo() {}
};
// functor used by boost to iterate over the tuple
template <class Tuple>
struct functor
{
functor(Tuple t)
: m_tuple(t)
{
}
template <class X>
void operator()(X& x) const
{
using namespace boost::mpl;
using iter = typename find_if<Tuple, std::is_same < placeholders::_1, void (X::*)()> >::type;
using type = typename deref<iter>::type;
return (x.*std::get<type>(m_tuple))();
}
private:
Tuple m_tuple;
};
template <class Tuple>
functor<Tuple> make_functor(Tuple t)
{
return functor<Tuple>(t);
}
int main()
{
std::tuple<void (A::*)(), void (B::*)(), void (C::*)() > x(&A::aFoo, &B::bFoo, &C::c1Foo);
std::tuple<A, B, C> y;
boost::fusion::for_each(y, make_functor(x));
}
Live demo here:
http://coliru.stacked-crooked.com/a/e840a75f5b42766b
Related
I am curious how one would go about storing a parameter pack passed into a function and storing the values for later use.
For instance:
class Storage {
public:
template<typename... Args>
Storage(Args... args) {
//store args somehow
}
}
Basically I am trying to make a class like tuple, but where you don't have to specify what types the tuple will hold, you just pass in the values through the constructor.
So for instance instead of doing something like this:
std::tuple<int, std::string> t = std::make_tuple(5, "s");
You could do this:
Storage storage(5, "s");
And this way you could any Storage objects in the same vector or list. And then in the storage class there would be some method like std::get that would return a given index of an element we passed in.
Since run will return void, I assume all the functions you need to wrap can be functions that return void too.
In that case you can do it like this (and let lambda capture do the storing for you):
#include <iostream>
#include <functional>
#include <string>
#include <utility>
class FnWrapper
{
public:
template<typename fn_t, typename... args_t>
FnWrapper(fn_t fn, args_t&&... args) :
m_fn{ [=] { fn(args...); } }
{
}
void run()
{
m_fn();
}
private:
std::function<void()> m_fn;
};
void foo(const std::string& b)
{
std::cout << b;
}
int main()
{
std::string hello{ "Hello World!" };
FnWrapper wrapper{ foo, hello };
wrapper.run();
return 0;
}
OK, what you're asking is type erasure. Typical way of implementing it is via a virtual function inherited by a class template.
Live demo here: https://godbolt.org/z/fddfTEe5M
I stripped all the forwards, references and other boilerplate for brevity. It is not meant to be production code by any means.
#include<memory>
#include <iostream>
#include <stdexcept>
struct Fn
{
Fn() = default;
template<typename F, typename...Arguments>
Fn(F f, Arguments...arguments)
{
callable =
std::make_unique<CallableImpl<F, Arguments...>>(f, arguments...);
}
void operator()()
{
callable
? callable->call()
: throw std::runtime_error("empty function");
}
struct Callable
{
virtual void call() =0;
virtual ~Callable() = default;
};
template<typename T, typename...Args_>
struct CallableImpl : Callable
{
CallableImpl(T f, Args_...args)
: theCallable(f)
, theArgs(std::make_tuple(args...))
{}
T theCallable;
std::tuple<Args_...> theArgs;
void call() override
{
std::apply(theCallable, theArgs);
}
};
std::unique_ptr<Callable> callable{};
};
void f(int a)
{
std::cout << a << '\n';
}
int main(int, char*[])
{
Fn fx{f, 3};
fx();
char x = 'q';
Fn flambda( [x](){std::cerr << x << '\n';} );
flambda();
}
The "meat" of it lies here:
struct Callable
{
virtual void call() =0;
virtual ~Callable() = default;
};
template<typename T, typename...Args_>
struct CallableImpl : Callable
{
CallableImpl(T f, Args_...args)
: theCallable(f)
, theArgs(std::make_tuple(args...))
{}
T theCallable;
std::tuple<Args_...> theArgs;
void call() override
{
std::apply(theCallable, theArgs);
}
};
Callable is just the interface to access the object. Enough to store a pointer to it and access desired methods.
The actual storage happens in its derived classes:template<typename T, typename...Args_> struct CallableImpl : Callable. Note the tuple there.
T is for storing the actual object, whatever it is. Note that it has to implement some for of compile-time interface, in C++ terms referred to as a concept. In that case, it has to be callable with a given set of arguments.
Thus it has to be known upfront.
The outer structure holds the unique_ptr to Callable but is able to instantiate the interface thanks to the templated constructor:
template<typename F, typename...Arguments>
Fn(F f, Arguments...arguments)
{
callable =
std::make_unique<CallableImpl<F, Arguments...>>(f, arguments...);
}
What is the main advantage of it?
When done properly, it has value semantics. Effectively, it can be used to represent a sort of polymorphism without derivation, note T doesn't have to have a common base class, it just has to be callable in one way or another; this can be used for addition, subtraction, printing, whatever.
As for the main drawbacks: a virtual function call (CallableImpl stored as Callable) which may hinder performance. Also, getting back the original type is difficult, if not nearly impossible.
In some code that I was reading, I found the usage of empty struct like so:
struct input_iterator_tag { };
struct bidirectional_iterator_tag { };
struct random_access_iterator_tag { };
So in the rest of the code, it was used as what they call tag dispatching.
I was wondering if there is other usage of empty structs.
from an older post I saw that :
three major reasons we use empty structs in C++ are:
a base interface
a template parameter
a type to help overload resolution. (tag dispatching if I am not wrong)
Could someone explain that please?
a type to help overload resolution. (tag dispatching if I am not wrong)
When you want to use a complex template specialization pattern on some function, you don't try to go at it directly, but rather write:
template <typename T1, typename T2, other things maybe>
int foo(T1 param1, T2 param2 and so on)
{
using tag = put your complex stuff here, which produces an empty struct
detail::foo_impl(tag, std::forward<T1>(param1), std::forward<T2>(param2) and so on);
}
Now, the compiler doesn't have to decide between competing choices of template specialization, since with different tags you get incompatible functions.
a base interface
struct vehicle {
// common members and methods,
// including (pure) virtual ones, e.g.
virtual std::size_t num_maximum_occupants() = 0;
virtual ~vehicle() = default;
};
namespace mixins {
struct named { std::string name; };
struct wheeled { int num_wheels; public: rev() { }; };
} // namespace mixins
struct private_sedan : public vehicle, public wheeled, named {
// I dunno, put some car stuff here
//
// and also an override of `num_maximum_occupants()`
};
Making the base struct completely empty is perhaps not that common, but it's certainly possible if you use mixins a lot. And you could check for inheritance from vehicle (although I'm not sure I'd do that).
a template parameter
Not sure what this means, but venturing a guess:
template <typename T>
struct foo { };
template <typename T, typename N>
struct foo<std::array<T, N>> {
int value = 1;
};
If you now use foo<T>::value in a function, it will work only if T is int with few (?) exceptions.
I also tried to come up with examples:
as a base interface
// collection of very abstract vehicles
#include <vector>
struct Vehicle {};
struct Car : Vehicle {
int count_of_windows;
};
struct Bike : Vehicle {
int size_of_wheels;
};
std::vector<Vehicle> v{Bike{}, Car{}};
as a template parameter
// print same number in 3 different formats
#include <iostream>
struct dec {};
struct hex {};
struct octal {};
template<typename HOW = dec>
void print_me(int v);
template<>
void print_me<dec>(int v) {
auto f = std::cout.flags();
std::cout << std::dec << v << std::endl;
std::cout.flags(f);
}
template<>
void print_me<hex>(int v) {
auto f = std::cout.flags();
std::cout << std::hex << v << std::endl;
std::cout.flags( f );
}
template<>
void print_me<octal>(int v) {
auto f = std::cout.flags();
std::cout << std::oct << v << std::endl;
std::cout.flags(f);
}
int main() {
print_me(100);
print_me<hex>(100);
print_me<octal>(100);
}
a type to help overload resolution
// add a "noexcept" qualifier to overloaded function
// the noexcept version typically uses different functions
// and a custom "abort" handler
#include <iostream>
struct disable_exceptions {};
void is_number_1() {
int v;
std::cin >> v;
if (v != 1) {
throw new std::runtime_error("AAAA");
}
}
void is_number_1(disable_exceptions) noexcept {
int v;
// use C function - they don't throw
if (std::scanf("%d", &v) != 1) {
std::abort();
}
if (v != 1) {
std::abort();
}
}
int main() {
is_number_1();
is_number_1(disable_exceptions());
}
The example about "tag dispatching" can be found on cppreference iterator_tags. The iterator_category() member of an iterator is used to pick a different overload. That way you could write a different algorithm if for example iterator is forward_iterator, where you can only go forward, or it is a bidirectional_iterator, where your algorithm could change because you may walk back.
I have a number of callback functions with different signatures. Ideally, I would like to put these in a vector and call the appropriate one depending on certain conditions.
e.g.
void func1(const std::string& value);
void func2(const std::string& value, int min, int max);
const std::vector<std::function<void(std::string)>> functions
{
func1,
func2,
};
I realise the above isn't possible, but I wonder if there are any alternatives I should consider. I haven't been able to find any yet, and I've experimented with std::bind but not managed to achieve what I want.
Is such a thing possible?
You haven't said what you expect to be able to do with func2 after putting it in a vector with the wrong type.
You can easily use std::bind to put it in the vector if you know the arguments ahead of time:
const std::vector<std::function<void(std::string)>> functions
{
func1,
std::bind(func2, std::placeholders::_1, 5, 6)
};
Now functions[1]("foo") will call func2("foo", 5, 6), and will pass 5 and 6 to func2 every time.
Here's the same thing using a lambda instead of std::bind
const std::vector<std::function<void(std::string)>> functions
{
func1,
[=](const std::string& s){ func2(s, func2_arg1, func2_arg2); }
};
If you don't know the arguments yet, you can bind references to some variables:
int func2_arg1 = 5;
int func2_arg2 = 6;
const std::vector<std::function<void(std::string)>> functions
{
func1,
std::bind(func2, std::placeholders::_1, std::ref(func2_arg1), std::ref(func2_arg2))
};
Now functions[1]("foo") will call func2("foo", func2_arg1, func2_arg2), and you can assign new values to the integers to pass different arguments to func2.
And using a lambda function instead of std::bind
const std::vector<std::function<void(std::string)>> functions
{
func1,
[&](const std::string& s){ func2(s, func2_arg1, func2_arg2); }
};
This is pretty ugly though, as you need to keep the int variables around for as long as the callable object (the closure or the bind expression) referring to them exists.
What you want is possible through polymorphism. The idea is to create a class with a specific signature, which at runtime will call different methods. For example:
#include <iostream>
#include <functional>
#include <memory>
#include <vector>
void foo(int) {
std::cout << "I'm foo!\n";
}
int bar(char, double) {
std::cout << "I'm bar!\n";
}
class MyFunction {
public:
virtual ~MyFunction(){}
virtual void operator()() = 0;
};
class MyFunctionA : public MyFunction {
public:
virtual void operator()() {
foo(4);
}
};
class MyFunctionB : public MyFunction {
public:
MyFunctionB(std::function<int(char,double)> f, char arg1, double arg2) : fun_(f), arg1_(arg1), arg2_(arg2) {}
virtual void operator()() {
fun_(arg1_, arg2_);
}
private:
std::function<int(char,double)> fun_;
char arg1_;
double arg2_;
};
int main() {
using MyFunPtr = std::unique_ptr<MyFunction>;
std::vector<MyFunPtr> v;
v.emplace_back(new MyFunctionA());
v.emplace_back(new MyFunctionB(bar, 'c', 3.4));
for ( auto&& myfun : v ) {
(*myfun)();
}
return 0;
}
You can make the derived classes as complicated as you need be, but since in the end they all have the same interface you will be able to call all of them.
For C++ 17 std::variant can be used for holding std::functions with different signatures. In this case, the function std::holds_alternative allows you to distinguish between them at runtime:
Sample:
#include <variant>
#include <iostream>
#include <functional>
#include <vector>
using FooInt = std::function<void(int)>;
using FooStr = std::function<void(std::string)>;
using FooVariant = std::variant<FooInt, FooStr>;
void foo(int a){
std::cout << a << std::endl;
}
void bar(std::string a){
std::cout << a << std::endl;
}
int main()
{
std::vector<FooVariant> v;
v.push_back(foo);
v.push_back(bar);
for(auto& f: v){
if (std::holds_alternative<FooInt>(f))
std::get<FooInt>(f)(1);
else if (std::holds_alternative<FooStr>(f))
std::get<FooStr>(f)("hello");
}
}
Direct answer to your question is "NO". Any runtime container would only let you store objects of the same type and std::function<> instantiated with different signatures will be different data types.
Generally the reason you may want to have "a vector of functions with different signatures" is when you have something like the below (three step processing where input interface is unified (buffer& buf and output interface is unified on_event(Event evt)), but the layer in the middle is heterogeneous process_...(...)
receive_message(buffer& buf)
switch(msg_type(buf))
case A:
case B:
...
process_A(A& a, One x, Two y)
...
dispatch(Event evt);
...
process_B(B& b, Three x);
...
dispatch(Event evt);
...
In a solution not involving metaprogramming you'd typically pre-cook a functor doing the end-to-end at initialization time and store those in the vector:
vector <std::function<void(buffer& buf)>> handlers;
If you've got an int and a string, you cannot put them in one vector but you can put them in one struct or std::tuple<>. The same applies for two function types.
std::function erases the exact type of the function object but preserves the function call signature. If you cannot bind the extra arguments in advance as Jonathan Wakely recommends, you can use a boost::variant< std::function<...>, std::function<...> > as your vector member. At the call site you can then check if the vector contains the right kind of function object and call it accordingly.
Not sure how useful this would be for you, it is based on boost::any, redundant parameters are ignored. You can add try...catch for boost::bad_any_cast to prevent crash in case of mismatch between arguments' and parameters' types. Though I think regular std::bind is a better choice.
DEMO
#include <boost/any.hpp>
#include <functional>
#include <vector>
#include <cstddef>
#include <memory>
#include <tuple>
#include <utility>
#include <iostream>
#include <string>
struct IGenericFunction
{
virtual ~IGenericFunction() = default;
virtual void call(boost::any a1 = boost::any{}
, boost::any a2 = boost::any{}
, boost::any a3 = boost::any{}
, boost::any a4 = boost::any{}) = 0;
};
template <typename... Args>
class GenericFunction : public IGenericFunction
{
public:
GenericFunction(std::function<void(Args...)> f) : _f{ f } {}
virtual void call(boost::any a1 = boost::any{}
, boost::any a2 = boost::any{}
, boost::any a3 = boost::any{}
, boost::any a4 = boost::any{}) override
{
call_func(std::make_tuple(a1, a2, a3, a4)
, std::make_index_sequence<sizeof...(Args)>{});
}
private:
template <typename Tuple, std::size_t... Indices>
void call_func(Tuple t, std::index_sequence<Indices...> s)
{
_f(boost::any_cast<
typename std::tuple_element<Indices, Params>::type
>(std::get<Indices>(t))...);
}
std::function<void(Args...)> _f;
using Params = std::tuple<Args...>;
};
template <typename... Args>
std::shared_ptr<IGenericFunction> make_generic_function_ptr(void(*f)(Args...))
{
return std::make_shared<GenericFunction<Args...>>(f);
}
void func1(const std::string& value)
{
std::cout << "func1 " << value << std::endl;
}
void func2(const std::string& value, int min, int max)
{
std::cout << "func2 " << value << " " << min << " " << max << std::endl;
}
int main()
{
std::vector<std::shared_ptr<IGenericFunction>> functions;
functions.push_back(make_generic_function_ptr(&func1));
functions.push_back(make_generic_function_ptr(&func2));
for (auto f : functions)
{
f->call(std::string("abc"), 1, 2);
}
}
As JBL mentioned: how would you call them, if you don't know their signatures?
Think about turning your min, max arguments into a parameter type with some base class Parameter, the callback signature will be void(const std::string&, const Parameter&) or void(const std::string&, const Parameter*) in case you wish nullptr to indicate no additional parameters. Now your callbacks will need to check if they were given the right parameters if any. That may be done by using a visitor, typeid or an enum. There's pros and cons to all of those.
How will you decide on which callback to call? I think you should turn your C-style callbacks into handler objects, they might implement a function bool canHandle(const Parameter&) to test if the handler is applicable to the parameters presented.
Jonathan Wakely and Svalorzen present their approach where the parameters and the function are one and the same object (1-to-1 relationship). In this example they are separate (in case you have multiple-to-multiple relationships):
#include <cassert>
#include <string>
#include <typeinfo>
#include <vector>
class ParameterBase {
public:
ParameterBase(const std::string& value) : m_value(value) { }
virtual ~ParameterBase() { }
const std::string& GetValue() const { return m_value; }
private:
std::string m_value;
};
class HandlerBase {
public:
virtual bool CanHandle(const ParameterBase& params) const = 0;
virtual void Handle(const ParameterBase& params) = 0;
};
class Handler1 : public HandlerBase {
public:
class Parameter : public ParameterBase {
public:
Parameter(const std::string& value) : ParameterBase(value) { }
~Parameter() { }
};
bool CanHandle(const ParameterBase& params) const { return typeid(Parameter) == typeid(params); }
void Handle(const ParameterBase& params) {
assert(CanHandle(params));
const Parameter& p = static_cast<const Parameter&>(params);
// implement callback1
}
};
void foo(const std::vector<HandlerBase*>& handlers) {
Handler1::Parameter params("value");
for(auto handler : handlers)
if(handler->CanHandle(params)) {
handler->Handle(params);
// no break: all handlers may handle params
// with break: only first handler (if any) handles params
}
}
I tried to use the function pointer, and cast std::function<int(int)>* to void*, it can be compiled successful, but sometimes it will cause segmentation fault:
int Fun(int a)
{
std::cout << a << std::endl;
return ++(++a);
}
int main()
{
std::function<int(int)> originPFun = Fun;
void *ppFun;
// ppFun = (void*)&Fun; // This way will cause segmentation fault
ppFun = (void*)&originPFun; // This way can run seuccessful and get right result
std::function<int(int)> *pFun = (std::function<int(int)>*)(ppFun);
std::cout << (*pFun)(5) << std::endl;
system("pause");
return 0;
}
This is easier to explain with some code so I'll give an example first:
#include <iostream>
#include <vector>
class Base {
public:
int integer;
Base() : integer(0) {}
Base(int i) : integer(i) {}
};
class Double: public Base {
public:
Double(int i) { integer = i * 2; }
};
class Triple: public Base {
public:
Triple(int i) { integer = i * 3; }
};
template<typename T>
Base* createBaseObject(int i) {
return new T(i);
};
int main() {
std::vector<Base*> objects;
objects.push_back(createBaseObject<Double>(2));
objects.push_back(createBaseObject<Triple>(2));
for(int i = 0; i < objects.size(); ++i) {
std::cout << objects[i]->integer << std::endl;
}
std::cin.get();
return 0;
}
I am trying to make a function that will return a Base pointer to an object that is derived from Base. In the above code the function createBaseObject allows me to do that but it restricts me in that it can only create dervied classes that take a single argument into their constructor.
For example if I wanted to make a derived class Multiply:
class Multiply: public Base {
public:
Multiply(int i, int amount) { integer = i * amount; }
};
createBaseObject wouldn't be able to create a Multiply object as it's constructor takes two arguments.
I want to ultimately do something like this:
struct BaseCreator {
typedef Base* (*funcPtr)(int);
BaseCreator(std::string name, funcPtr f) : identifier(name), func(f) {}
std::string identifier;
funcPtr func;
};
then, for example, when I get input matching identifier I can create a new object of whatever derived class associates with that identifier with whatever arguments were input too and push it to the container.
After reading some of the replies I think something like this would suit my needs to be able to procedurally create an instance of an object? I'm not too wise with templates though so I do not know whether this is legal.
struct CreatorBase {
std::string identifier;
CreatorBase(std::string name) : identifier(name) {}
template<typename... Args>
virtual Base* createObject(Args... as) = 0;
};
template<typename T>
struct Creator: public CreatorBase {
typedef T type;
template<typename... Args>
Base* createObject(Args... as) {
return new type(as...);
}
};
Okay here's another semi-solution I've managed to come up with so far:
#include <boost\lambda\bind.hpp>
#include <boost\lambda\construct.hpp>
#include <boost\function.hpp>
using namespace boost::lambda;
boost::function<Base(int)> dbl = bind(constructor<Double>(), _1);
boost::function<Base(int, int)> mult = bind(constructor<Multiply>(), _1, _2);
Just this has the same limits as the original in that I can't have a single pointer that will point to both dbl and mult.
C++11 variadic templates can do this for you.
You already have your new derived class:
class Multiply: public Base {
public:
Multiply(int i, int amount) { integer = i * amount; }
};
Then change your factory:
template<typename T, typename... Args>
Base* createBaseObject(Args... as) {
return new T(as...);
};
And, finally, allow the arguments to be deduced:
objects.push_back(createBaseObject<Multiply>(3,4));
Live demo.
As others have said, though, it does all seem a little pointless. Presumably your true use case is less contrived.
Why not provide multiple overloads with templated parameters?
template<typename TBase, TArg>
Base* createBaseObject(TArg p1) {
return new TBase(p1);
};
template<typename TBase, TArg1, TArg2>
Base* createBaseObject(TArg p1, TArg2 p2) {
return new TBase(p1, p2);
};
Use variadic templates:
template <typename R, typename ...Args>
Base * createInstance(Args &&... args)
{
return new R(std::forward<Args>(args)...);
}
Usage: objects.push_back(createInstance<Gizmo>(1, true, 'a'));
It's a bit hard to see why you would want this, though, as you might as well just say:
objects.push_back(new Gizmo(1, true, 'a'));
Even better would be to declare the vector to carry std::unique_ptr<Base> elements.
I have a container class, we'll call it
template <class T> CVector { ... }
I want to do something different with this class when T is a pointer type, e.g. something along the lines of:
template <class T*> CVector< SomeWrapperClass<T> >;
where SomeWrapperClass is expecting the type of the pointed to thing as its parameter. Unfortunately, this syntax doesn't quite work and with some digging, I haven't found a good way to get something like this working.
Why do it this way? I want to change, in a very large app, how some of our containers work when the type they're specialized on is a pointer vs. not a pointer - and ideally, i'd like to do it without changing the ~1,000 places in the code where there are things like CVector<Object*> vs CVector<int> or some such - and playing games with partial specializations seemed to be the way to go.
Am I on crack here?
If I understand you correctly, this might do what you want:
template<typename T>
class CVector { ... };
template<typename T>
class CVector<T*> : public CVector< SomeWrapperClass<T> > {
public:
// for all constructors:
CVector(...) : CVector< SomeWrapperClass<T> >(...) {
}
};
It adds an additional layer of inheritance to trick CVector<T*> into being a CVector< SomeWrapperClass<T> >. This might also be useful in case you need to add additional methods to ensure full compatibility between the expected interface for T* and the provided interface for SomeWrapperClass<T>.
This works just fine in C++...
#include <iostream>
template <class T>
class CVector
{
public:
void test() { std::cout << "Not wrapped!\n"; }
};
template <class T>
class CVector<T*>
{
public:
void test() { std::cout << "Wrapped!\n"; }
};
int main()
{
CVector<int> i;
CVector<double> d;
CVector<int*> pi;
CVector<double*> pd;
i.test();
d.test();
pi.test();
pd.test();
}
I don't think you can specialize a class using the syntax you describe... I don't know how that could possibly work. What you can do is specialize the class for pointers and re-implement its guts using the wrapper class around the raw pointers. I'm not sure if it will help, but this article describes specializing templates for pointers.
The Boost type traits library can help you achieve this. Check out the is_pointer type trait.
#include <boost/type_traits.hpp>
#include <iostream>
#include <vector>
using namespace std;
template <class T>
class CVector {
public:
void addValue(const T& t) {
values_.push_back(t);
}
void print() {
typedef boost::integral_constant<bool,
::boost::is_pointer<T>::value> truth_type;
for (unsigned int i = 0; i < values_.size(); i++)
doPrint(values_[i], truth_type());
}
private:
void doPrint(const T& t, const boost::false_type&) {
cout << "Not pointer. Value:" << t << endl;
}
void doPrint(const T& t, const boost::true_type&) {
cout << "Pointer. Value: " << *t << endl;
}
std::vector<T> values_;
};
int main() {
CVector<int> integers;
integers.addValue(3);
integers.addValue(5);
integers.print();
CVector<int*> pointers;
int three = 3;
int five = 5;
pointers.addValue(&three);
pointers.addValue(&five);
pointers.print();
}
I don't think templates are quite that flexible.
A very brute force approach would be to specialize for all of your pointer types...which defeats the problem of using templates.
Could you have a different CVector class that is used only for vectors of pointers?
I agree with rlbond's answer. I have modified it a little bit to suit your need. CVector can be a derived class of the CVector itself. You can then use different members and functions for it.
#include <iostream>
#include <string>
template <class T>
class CVector
{
public:
void test() { std::cout << "Not wrapped!\n"; }
void testParent() { std::cout << "Parent Called\n";}
};
template <class T>
class CVector<T*>:
public CVector<T>
{
public:
void test(std::string msg) { std::cout << msg; testParent(); }
};
int main()
{
CVector<int> i;
CVector<double> d;
CVector<int*> pi;
CVector<double*> pd;
i.test();
d.test();
pi.test("Hello\n");
pd.test("World\n");
system("pause");
}