From: DeMarcus on
On 2010-05-24 17:47, Francis Glassborow wrote:
> DeMarcus wrote:
>> I can do this.
>>
>> template<class T>
>> class SomeTemplate
>> {
>> };
>>
>> typedef InheritedComposition<SomeTemplate> ST;
>>
>>
>> But I cannot do this.
>>
>> class SomeClass
>> {
>> };
>>
>> typedef InheritedComposition<SomeClass> SC;
>>
>>
>> How can I make SomeClass look like a template with zero arguments?
>>
>>
>> Thanks,
>> Daniel
>>
>
> My instinct says that the answer lies in default template arguments. Now
> you want the default argument to be a type you would never use anywhere
> else so:
>
> struct empty_default_type {};
>
> template<typename T = empty_defgault_type> SomeClass {};
>
> Just an idea to play with. I don't have the time to fleash it out and
> think about the ramifications.
>


I found a way to use template partial specialization. I'm not sure if
this is good design but it seems to work.

template<template<typename...> class Object, typename... Tn>
class InheritedComposition
{
public:

template<typename... Args>
InheritedComposition( Args... args )
: instance_( std::forward<Args>(args)... ) {}

inline Object<Tn...>& instance()
{
return instance_;
}

private:

Object<Tn...> instance_;

};


// Now partial specialize that template but use Tn for something it's
// not used for in the primary template.

template<class>
class Dummy {}

template<typename T>
class InheritedComposition<Dummy, T>
{
public:

template<typename... Args>
InheritedComposition( Args... args )
: instance_( std::forward<Args>(args)... ) {}

inline T& instance()
{
return instance_;
}

private:

T instance_;

};

// Now the typedef works.
class SomeClass
{
};

typedef InheritedComposition<Dummy, SomeClass> SC;


It feels like it's bad design reusing the Tn template argument for
something else it was originally designed for, don't you think?

In the future we may be able to swap Dummy for the following TemplateCast.

template<typename T>
using TemplateCast = T;

and remove the template partial specialization completely and then use
the following.

typedef InheritedComposition<TemplateCast, SomeClass> SC;

Or maybe TemplateCast should be named Identity instead.



--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

From: Johannes Schaub (litb) on
DeMarcus wrote:

> I think I found it!
>
> This would work, right? I can't try it since gcc 4.5 doesn't support
> template aliases yet.
>
> // Original universal template.
> template<template<typename...> class Object, typename... Tn>
> class InheritedComposition
> {
> public:
>
> template<typename... Args>
> InheritedComposition( Args... args )
> : instance_( std::forward<Args>(args)... ) {}
>
> inline Object<Tn...>& instance()
> {
> return instance_;
> }
>
> private:
>
> Object<Tn...> instance_;
>
> };
>
> // New template cast.
> template<typename T>
> using TemplateCast = T;
>
> // Typedef that didn't work before now works!
> typedef InheritedComposition< TemplateCast, SomeClass > SC;
>
>
> What do you think? Does your compiler support template aliases yet so
> you could try it out for me?

I believe too that this should work now. Template aliases seem to be enough of an own entity that they can be passed as template template arguments.
I first tried std::identity on that, since i thought it wouldn't work with template aliases. But with std::identity one has to put "::type" afterwards within the template. Your template alias does not need that and wirks with the original template. I
think such an identity alias would be a nice addition to the standard library.
Among many other usecases of it (like simplifying the synax of C++ declarations, allowing to write a conversion function that deduces array bounds or function parameter lists), this seems to me like a very good reason to add it. Maybe simply call it
"std::alias"?

template<typename T>
using alias = T;


--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

First  |  Prev  | 
Pages: 1 2
Prev: has_interface trait
Next: numeric_limits and constexpr