Template Member Function Pointers - c++

I currently have a problem, VS2010 nags that "TFunctionPointer" used in the constructor of "Nuke" & as datamember is undefined. Could someone please explain to me why this is ? Any help is very much appreciated.
template<typename T>
typedef void (T::* TFunctionPointer)();
class Nuke
{
public:
Nuke( TFunctionPointer pFunction );
virtual ~Nuke();
private:
TFunctionPointer m_pFunction;
};
// EDIT
What I'm trying to do is allow a function pointer to any type of class to be stored and called on destruction of the Nuke object. A twist on RAII. But I guess it isn't possible. Thanks for the help guys.
// EDIT
Apparently Boost::shared_ptr is what I was looking for.

Template typedefs aren't legal in C++.
What you can do though (in both "old" and "new" C++) is this:
template <typename T>
struct TFunctionPointer
{
typedef void (T::*Type)();
};
class Nuke
{
public:
Nuke( TFunctionPointer<Nuke>::Type pFunction );
virtual ~Nuke();
private:
TFunctionPointer<Nuke>::Type m_pFunction;
};

C++ doesn't support template typedefs, so template<typename T> typedef is illegal.
If you can use C++11 you might be able to use template aliases. I'm not quite sure if that is possible with memberfunction pointers and can't guarantee the syntax is correct, but I would expect it to be something like the following:
template <typename T>
using TFunctionPointer = void(T::*)();
Of course VS2010 probably doesn't support that anyways.
Anyways your Nuke class doesn't give a type for the TFunctionPointer, so even if that typedef where legal, you are trying to pass a template instead of a concrete type, which isn't possible.
You could wrap your function pointer into a type and use a properinstantiation:
template<typename T> struct FunctionPointer { typedef void (T::*Type)(); };
class Nuke {
public:
Nuke(FunctionPointer<Nuke>::Type pFunction);
virtual ~Nuke();
private:
FunctionPointer<Nuke>::Type m_pFunction;
};

Related

Preventing accidental hiding (of a method provided by CRTP mixin)

I have a bunch of useful functions on the object of type T. Here T needs to provide some interface for the functions to work with it. There are several common implementations of the interface. So I made them working as mixins using CRTP.
template<class T>
struct InterfaceImpl {
using ImplType = InterfaceImpl<T>;
int foo();
...
};
struct MyData : public InterfaceImpl<MyData> {
...
};
template<class T>
void aUsefulFunction(T& t) {
//Working with `t`.
//This cast is to workaround an accidental hiding of `foo` by MyData.
static_cast<T::ImplType&>(t).foo();
}
I want the implementation InterfaceImpl (and other implementations also) are provided as it is in some reason. Hiding some of their methods could be very dangerous. Are their any way to enforce no overriding by child classes? I read link on a similar question, but the discussion does not give a satisfactory solution. If there is no reasonable way, I expect that the casting in the above code could give some safety. Or are there any other solution to solve the problem?
You can create a traits to see if T has foo and using static_assert on that:
typename <typename T, typename ...Ts>
using foo_type = decltype(std::declval<T>().foo(std::declval<Ts>()...));
template <typename T>
using has_foo = is_detected<foo_type, T>;
template<class T>
struct InterfaceImpl {
static_assert(!has_foo<T>::value, "T should not have foo method");
using ImplType = InterfaceImpl<T>;
int foo();
};
MyData can still hide foo with MyData::foo(int) or similar, but you will have compilation error instead if calling the wrong method.

C++ a way to have a typedef template to a member function?

Title pretty much says it all!
Is there any pretty/simple way to do this? Since function pointers can't point to member functions and a member function needs to know the class the members belong to but in this case there is no such information since the class the function comes from will differ. Only standard library please!
template <class A>
typedef void (A::*Function)(Parameters p);
You could try wrapping it in a struct like this:
template <class T>
struct method_ptr
{
typedef void (T::*Function)(Parameters p);
};
class A
{
public:
void foobar(Parameters);
};
// ...
method_ptr<A>::Function pfoobar = &A::foobar;
Untested, but this should work with a C++11 compiler:
template <typename T>
using Function = void (T::*)(Parameters p);
Now the interesting question is what is the problem for this to be the solution.

Changing deleter for std::unique_ptr

I want to change default_deleter for std::unique_ptr. This is quite easy to achieve, but there is one inconvenient - I have to declare variables using 2 template parameters instead of one, something like this:
std::unique_ptr<MyType, MyDeleter<MyType>> myVar;
As you may see the declaration is long and I have a feeling I can use a shorter version, but I don't know how:)
Is it possible to declare some kind of MyUniquePtr<T> that will be the same as std::unique_ptr<T, MyDeleter<T>>?
EDIT: Matthieu M. already answered, but unfortunately I can't use this feature in Visual Studio as it's not implemented. Is there other way to have this behavior?
Actually it is, using template aliases:
template <typename T>
using MyUniquePtr = std::unique_ptr<T, MyDeleter<T>>;
If your compiler doesn't do template aliases yet, here's the C++03 idiom:
template <typename T>
struct MyUniquePtr {
typedef std::unique_ptr<T, MyDeleter<T> > type;
};
MyUniquePtr<MyType>::type var;
The setup is uglier, but the resulting usage is almost as short: you just need to add ::type.
Does your deleter need to be templated on the type of the object being deleted, or is it sufficient for the function call operator to be templated on the type of object being deleted?
Instead of:
template<typename T>
struct MyDeleter
{
void operator()(T* p) const { /* ... */ }
};
Can you write:
struct MyDeleter
{
template<typename T>
void operator()(T* p) const { /* ... */ }
};
This, of course, depends on what state MyDeleter has to maintain.
Another way conforming to c++03 is a subclass, which unfortunately requires you to reproduce the constructors. (This can be done easier, if your compiler supports variadic template arguments, which may be the case for current MSVC.)
template <class T>
class MyUniquePtr : public std::unique_ptr< T, MyDeleter<T> > {
public:
MyUniquePtr(args...) : std::unique_ptr< T, MyDeleter<T> >(args...) { }
};
You might want to consider writing your own version of a make_unique style function instead specialized for your custom allocation / deletion strategy. This also has the advantage that you can perform any specialized resource acquisition / allocation in an exception safe way. You can then declare your unique_ptr as auto and let type deduction work for you.

Raise an exception for non-pointer template class?

I've got this queue class, actually, several that suffer from the same issue - performance will be poor if compiled with a type that has a lengthy copy ctor - the queue is locked during push/pop and the longer it is locked, the greater the chance of contention. It would be useful if the class would not compile if some developer tried to compile it with a 10MB buffer class, (instead of a pointer to it).
It seems that there is no easy way to restrict template parameters to base classes or any other type.
Is there some bodge I can use so that my class will not compile if the parameter is not a pointer to a class instance?
You can do this in several ways. As another answer points out you can do it with a static_assert (preferably from C++11/Boost although you can roll your own), although I'd recommend checking if it is actually a pointer and not just relying on the size. You can either roll your own or use an existing trait (available in C++11 too) depending on what system you're using:
template <typename T>
struct is_pointer {
enum { value = 0 };
};
template <typename T>
struct is_pointer<T*> {
enum { value = 1 };
};
template <typename T>
struct container {
static_assert(is_pointer<T>::value, "T must be a pointer");
void push(const T&);
T pop();
};
struct foo {};
int main() {
container<foo*> good;
container<foo> fail;
}
But that raises a bigger point. If your requirement is that you only ever point to things, why not interpret the template parameter like that to begin with? E.g. make your container:
template <typename T>
struct container {
void push(const T*);
T *pop();
};
instead of allowing people to specify non-pointer types in the first place?
Finally if you don't want to go down the static_assert road you can just specialise the container for pointer types only and not implement it for non-pointers, e.g.:
template <typename T>
struct container;
template <typename T>
struct container<T*> {
void push(const T*);
T *pop();
};
struct foo {};
int main() {
container<foo*> good;
container<foo> fail;
}
This still requires explicitly making the type a pointer, still causes compile time failure for non-pointer types, but doesn't need a static_assert or way of determining if a type is a pointer.
"Is there some bodge I can use so that my class will not compile if the parameter is not a pointer to a class instance?"
Not a bodge, but:
template<class T>
class MyContainer
{
public:
void AllMemberFunctions( T* in ){}
void OnlyAcceptTStars( T* in ){}
};
The user defines the type being held, and your functions only accept or handle pointers to that type.
(Or do what STL does, assume some intelligence on the part of the user and forget about the issue.)
Use a variant of static assert (just google for many possible implementations). Something like BOOST_STATIC_ASSERT(sizeof(T) <= sizeof(void*)) should do the trick.
Yes, you can do it using static_assert. For example,
template<int N>
class Queue
{
static_assert(N < size, "N < size violated");
...
};

Alias for a C++ template?

typedef boost::interprocess::managed_shared_memory::segment_manager
segment_manager_t; // Works fine, segment_manager is a class
typedef boost::interprocess::adaptive_pool
allocator_t; // Can't do this, adaptive_pool is a template
The idea is that if I want to switch between boost interprocess' several different options for shared memory and allocators, I just modify the typedefs. Unfortunately the allocators are templates, so I can't typedef the allocator I want to use.
Is there a way to achieve an alias to a template in C++? (Except for the obvious #define ALLOCATOR_T boost::interprocess::adaptive_pool)
Yes, (if I understand your question correctly) you can "wrap" the template into a struct like:
template<typename T>
class SomeClass;
template<typename T>
struct MyTypeDef
{
typedef SomeClass<T> type;
};
and use it as:
MyTypeDef<T>::type
Edit: C++0x would support something like
template<typename T>
using MyType = SomeClass<T>;
Edit2: In case of your example
typedef boost::interprocess::adaptive_pool allocator_t;
can be
template<typename T>
struct allocator_t
{
typedef boost::interprocess::adaptive_pool<T> type;
}
and used as
allocator_t<SomeClass>::type
C++ doesn't support this, though it is slated to be fixed in the new standard. You might get away with deriving a new class template from adaptive_pool if there are no non-trivial constructors (or if you're happy to write a few forwarding constructors).
template <class T>
class allocator_t : public adaptive_pool<T> {
public:
// Just making up a forwarding constructor as an example. I know nothing
// anything about adaptive_pool.
allocator_t(int arg1, float arg2) : adaptive_pool<T>(arg1, arg2) { }
};
EDIT: Forget this answer. My vote goes to #Akanksh.