Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it possible to specialize a template definition based on the existence of a nested typedef of a template type parameter?

I have a template, template <typename T> class wrapper, that I would like to specialize based on the existence of typename T::context_type. If typename T::context_type is declared, then the constructors and assignment operator overloads of the wrapper<T> instantiation should accept a mandatory typename T::context_type parameter. Additionally, wrapper<T> objects would store "context" in the member data. If typename T::context_type does not exist, then the constructors and assignment operator overloads of wrapper<T> would take one less parameter and there would be no additional data member.

Is this possible? Can I get the following code to compile without changing the definitions of config1, config2, and main()?

#include <iostream>

template <typename T, bool context_type_defined = true>
class wrapper
{
public:
    typedef typename T::context_type context_type;

private:
    context_type ctx;

public:
    wrapper(context_type ctx_)
        : ctx(ctx_)
    {
        std::cout << "T::context_type exists." << std::endl;
    }
};

template <typename T>
class wrapper<T, false>
{
public:
    wrapper() {
        std::cout << "T::context_type does not exist." << std::endl;
    }
};

class config1 {
public:
    typedef int context_type;
};

class config2 {
public:
};

int main()
{
    wrapper<config1> w1(0);
    wrapper<config2> w2;
}
like image 205
Daniel Trebbien Avatar asked Sep 27 '11 21:09

Daniel Trebbien


People also ask

When we specialize a function template it is called?

The act of creating a new definition of a function, class, or member of a class from a template declaration and one or more template arguments is called template instantiation. The definition created from a template instantiation is called a specialization.

What is meant by template specialization Mcq?

Explanation: Template specialization is used when a different and specific implementation is to be used for a specific data type. In this program, We are using integer and character.

Are template specializations inline?

An explicit specialization of a function template is inline only if it is declared with the inline specifier (or defined as deleted), it doesn't matter if the primary template is inline.

What is template What is the need of template declare a template class?

Templates in c++ is defined as a blueprint or formula for creating a generic class or a function. Generic Programming is an approach to programming where generic types are used as parameters in algorithms to work for a variety of data types.In C++, a template is a straightforward yet effective tool.


1 Answers

Yes, it is possible. I have implemented such behavior in the past by using some metaprogramming tricks. The basic build blocks are:

BOOST_MPL_HAS_XXX_TRAIT_DEF, to define a metafunction predicate that will evaluate to a true type if the argument is of class type and has a nested type with a given name (context_type in your case).

http://www.boost.org/doc/libs/1_47_0/libs/mpl/doc/refmanual/has-xxx-trait-def.html

Boost.EnableIf, to define the specializations based on the previously defined trait.

http://www.boost.org/libs/utility/enable_if.html # See 3.1 Enabling template class specializations


Note that you may be able to get that behavior working directly with SFINAE, something like this may work:

template< typename T, typename Context = void >
class wrapper { ... }; // Base definition

template< typename T >
class wrapper< T, typename voif_mfn< typename T::context_type >::type > { ... }; // Specialization

However, I like the expressiveness of the solution based on traits and enable if.

like image 126
K-ballo Avatar answered Sep 22 '22 00:09

K-ballo