Alias for a C++ template? - c++

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.

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.

`typedef T this_type` that doesn't require T

Essentially, I need to know the current class so I can make macros that do things like:
typedef boost::shared_ptr<MyClass> sptr;
typedef boost::shared_ptr<const MyClass> csptr;
//etc
without having to put MyClass as a parameter to the macro. I've tried all sorts of ridiculous things like:
typedef decltype(*this) this_type;
but of course they don't work. Is there NOTHING that will let me work around this? I hoped C++11 would have given us something to hack together a way.
Two things: I would not make a fuss of having to repeat the type, and I would not use macros at all. You can use CRTP:
template <typename T>
struct sp_typedefs {
typedef std::shared_ptr<T> sptr; // [*]
typedef std::shared_ptr<const T> csptr;
};
Then in each type use inheritance to bring the typedefs into your type:
class MyType : sp_typedefs<MyType>
{
// ...
};
[*] Since you have tagged the question as C++11, you should be using std::shared_ptr which is standard, rather than boost::shared_ptr

Template Member Function Pointers

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;
};

templated recursive data types

I have a recursive data type like this:
template<typename T>
struct SomeType {
std::map<T, SomeType<T>> mapping;
};
SomeType<int> foo;
This works fine, but replacing std::map with std::unordered_map results in a compile error due to an incomplete type. Am I (or gcc) making an error somewhere? or is this just part of the standard?
I would also like to have the internal container determined by a template parameter (like std::stack and std::queue), but I can't figure out a way to do it since that would require SomeType to already be defined.
Incomplete example:
template<typename T, typename C = std::map<T, SomeType<[???]>>>
struct SomeType {
C mapping;
};
SomeType<int, [???]> foo;
I know this can be done with runtime indirection, but that's not what I'm looking for.
Your class is incomplete anywhere before the final } of its definition. So the mapping member is using incomplete type SomeType in its type's template arguments.
The standard does not allow this, and it is pure luck that it works with some STL containers.
Your second questions falls under the same answer -- it is illegal to do that in the first place.
You cannot define a template with recursive default parameters for obvious reasons. You also cannot instantiate standard library container templates on incomplete types, because the standard says so (otherwise it's undefined behaviour). The usual PIMPL idiom may help, though:
#include <map>
#include <memory>
template <typename T> class SomeType
{
typedef std::map<T, SomeType<T>> map_type;
typedef std::unique_ptr<map_type> map_ptr;
map_ptr pimpl;
public:
SomeType() : pimpl(new map_type) { }
};
While you cannot use incomplete types with containers, you can do it with smart pointers.
And while you cannot create template types with undefined types parameters, you can use some tricks here:
template<typename T, template <typename U, typename V, typename... Args> class Container = std::unordered_map >
struct SomeType {
Container<T, std::unique_ptr<SomeType> > mapping;
};

Automatic Evaluation Strategy Selection in C++

Consider the following function template:
template<typename T> void Foo(T)
{
// ...
}
Pass-by-value semantics make sense if T happens to be an integral type, or at least a type that's cheap to copy.
Using pass-by-[const]-reference semantics, on the other hand, makes more sense if T happens to be an expensive type to copy.
Let's assume for a second that you are writing a library. Ideally, as a library implementer, your job is to provide your consumers with a clean API that is both as generic and efficient as possible. How then, do you provide a generic interface that caters to both types of argument passing strategies?
Here is my first attempt at getting this to work:
#include <boost/type_traits.hpp>
template<typename T> struct DefaultCondition
{
enum {value = boost::is_integral<T>::value /* && <other trait(s)> */};
};
template< typename T, class Condition = DefaultCondition<T> > class Select
{
template<bool PassByValue = Condition::value, class Dummy = void> struct Resolve
{
typedef T type;
};
template<class Dummy> struct Resolve<false, Dummy>
{
typedef const T& type;
};
public: typedef typename Resolve<>::type type;
};
Typical usage:
template<typename T> class EnterpriseyObject
{
typedef typename Select<T>::type type;
public: explicit EnterpriseyObject(type)
{
// ...
}
};
struct CustomType {};
void Usage()
{
EnterpriseyObject<int>(0); // Pass-by-value.
(EnterpriseyObject<CustomType>(CustomType())); // Pass-by-const-reference.
}
This, of course, indirectly breaks implicit template argument deduction for non-class templates:
template<typename T> void Foo(typename Select<T>::type)
{
// ...
}
void Usage()
{
Foo(0); // Incomplete.
Foo<int>(0); // Fine.
}
This can be "fixed" with the Boost.Typeof library and a macro, a la the WinAPI:
#define Foo(Arg) ::Foo<BOOST_TYPEOF((Arg))>((Arg))
Though this is just a quasi-portable hack.
As you can see, my general approach is not really satisfactory for all cases.
As a hobbyist programmer, I neither have real-world experience nor do I have access to production-quality code for reference. I also realize that this might seem like a bad case of premature optimization, but I'm genuinely interested in a couple of things:
Do you, or have you used this type of optimization* in the past?
Does the Boost (or any other public) library already provide similar functionality?
If the answer to #1 or #2 is a 'yes' -- how is the non-class template case handled?
Are there any obvious pitfalls that I'm not seeing with something like this?
Finally, is this even a sane thing to do?
* Not profiled. ;)
Yes. All the time. I use it myself.
Yes, use Boost.Utility's Call Traits :)
Usage would be...
template <typename T>
void foo(boost::call_traits<T>::param_type param)
{
// Use param
}
As far as I know, non-class templates are passed-by-value unless it is faster to not. Thanks to partial template specialization, it can be customized relatively easily.
Sorry, didn't really read what you did, it just looked like exactly what I went through a few months ago. Therefore, can't really answer this one. My recommendation is just to read through Boost.Utility.
Of course!