是否可以基于模板类型参数的嵌套typedef的存在来专门化模板定义? [英] Is it possible to specialize a template definition based on the existence of a nested typedef of a template type parameter?

查看:218
本文介绍了是否可以基于模板类型参数的嵌套typedef的存在来专门化模板定义?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个模板, template< typename T>类包装器,我想专门化基于 typename T :: context_type 的存在。如果声明 typename T :: context_type ,则 wrapper 实例化的构造函数和赋值运算符重载应该接受强制的 typename T :: context_type 参数。另外, wrapper< T> 对象将在成员数据中存储上下文。如果 typename T :: context_type 不存在,则 wrapper< T> 的构造函数和赋值运算符重载将采用少一个参数,并且不会有其他数据成员。



这是否可能?我可以得到下面的代码来编译,而不改变 config1 config2 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不存在。 << std :: endl;
}
};

class config1 {
public:
typedef int context_type;
};

class config2 {
public:
};

int main()
{
wrapper< config1> w1(0);
wrapper< config2> w2;
}


解决方案

我已经通过使用一些元编程技巧在过去实现这样的行为。基本构建块是:



BOOST_MPL_HAS_XXX_TRAIT_DEF ,定义一个元函数谓词,如果参数是类类型,并且具有给定名称的嵌套类型(在您的情况下为context_type)。



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



Boost.EnableIf ,基于先前定义的特征定义专业化。



http://www.boost.org/libs/utility/enable_if.html 请参阅3.1启用模板类专业化






请注意,您可能能够直接使用SFINAE工作,类似这样的工作:

  template< typename T,typename Context = void> 
class wrapper {...}; //基本定义

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

然而,我喜欢基于traits的解决方案的表达能力, p>

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

解决方案

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.

这篇关于是否可以基于模板类型参数的嵌套typedef的存在来专门化模板定义?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆