是否可以根据模板类型参数的嵌套typedef的存在来专门化模板定义?

Dan*_*ien 5 c++ templates sfinae template-specialization

我有一个模板,template <typename T> class wrapper我想根据它的存在专门化typename T::context_type.如果typename T::context_type声明了,那么wrapper<T>实例化的构造函数和赋值运算符重载应该接受一个必需typename T::context_type参数.另外,wrapper<T>对象将在成员数据中存储"上下文".如果typename T::context_type不存在,则构造函数和赋值运算符重载wrapper<T>将减少一个参数,并且不会有其他数据成员.

这可能吗?我可以得到下面的代码不改变的定义编译config1,config2main()

#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;
}
Run Code Online (Sandbox Code Playgroud)

K-b*_*llo 4

对的,这是可能的。我过去曾通过使用一些元编程技巧来实现这种行为。基本构建块是:

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 { ... }; // Base definition

template< typename T >
class wrapper< T, typename voif_mfn< typename T::context_type >::type > { ... }; // Specialization
Run Code Online (Sandbox Code Playgroud)

但是,我喜欢基于特征和启用 if 的解决方案的表现力。