【问题标题】:Variadic template class specialization when empty pack空包时的可变模板类特化
【发布时间】:2018-03-26 09:33:20
【问题描述】:

我有一个 Data 类,其中包含大量功能。 该类还可能有 0 或 N 个附加类型,这些类型在实现该类的功能时是必需的:

 // in Data.h

template <typename T, typename ...Args>
class Data
{

    T f1();    
    T f2() const;    
    ... // skipped
    void f10(const T& v);

    // Pimpl
    struct Impl;
    Impl* _imp;
};

但是,如果sizeof...(Args) == 0sizeof...(Args) &gt; 0一些 函数(但不是全部!)的实现完全不同: 主要是内部私有实现类包含不同的类型。

// in DataImpl.h

template <typename T, typename ...Args>
struct ImplementationSpecificData;

template <typename T>
struct ImplementationSpecificData<T>
{
 // Some members available when sizeof...(Args) == 0

};

template <typename T, typename ...Args>
struct ImplementationSpecificData<T, Args...>
{
 // Some members available when sizeof...(Args) > 0
};

// The pimpl
template <typename T, typename ...Args> 
struct Data<T,Args...>::Impl
{
   // Some common members 
    ...

   // Following are specific whether sizeof...(Args) is > 0 or == 0
   ImplementationSpecificData<T,Args...> specificData;
};

// In Data.cpp
#include "DataImpl.h"

然后,对于具有依赖于 specificData 实现的函数,我想专门化这些函数,例如:

template <typename T, typename ...Args> 
T
Data<T,Args...>::f1() {
    // Case where sizeof...(Args) > 0
}

// 以下将不起作用,因为这是部分成员模板特化

template <typename T> 
T
Data<T>::f1() {
    // Case where sizeof...(Args) == 0
}

我尝试使用额外的 Enable 模板布尔值和需要的专门化函数

template <typename T, bool Enable, typename ...Args>
class Data
{
...
};

template <typename T, typename ...Args> 
T
Data<T, 
std::integral_constant<bool, sizeof...(Args) > 0>::value,
Args...>::f1() {
        // Case where sizeof...(Args) > 0
}

template <typename T, typename ...Args> 
T
Data<T, 
std::integral_constant<bool, sizeof...(Args) == 0>::value,
Args...>::f1() {
        // Case where sizeof...(Args) == 0
}

但这也不起作用,我得到以下信息:

用于声明的嵌套名称说明符 Data&lt;T, std::integral_constant&lt;bool, (sizeof...(Args) &gt; 0)&gt;::value, Args...&gt;:: 不引用类、类模板或类模板部分特化

有没有一种优雅的方式来实现这一点,而不用包含纯虚函数的基类和没有附加类型的派生类 D1 和具有附加类型的派生类 D2 污染我的 API: 这将需要在所有这 3 个类(Base、D1 和 D2)中维护类的函数签名(并且有很多函数)。

【问题讨论】:

  • Data&lt;T,Arg1,Args...&gt;::f1() ?
  • template T Data::f1() 也不起作用,我得到了嵌套名称说明符错误
  • 你试过std::integral_constant&lt;bool, (sizeof...(Args) &gt; 0)&gt;吗?我的意思是:添加几个括号以避免&gt; 0 中的&gt;integral_constant 的结尾混淆。
  • 我忘了加上括号,但即使使用它们也不起作用

标签: c++ templates variadic-templates


【解决方案1】:

在您的实现中使用重载/标签调度:

template <typename T, typename ...Args>
T f1_impl(Data<T, Args...>&) {
    // sizeof...(Args) > 0
}

template <typename T>
T f1_impl(Data<T>&) {
    // sizeof...(Args) == 0
}

template <typename T, typename ...Args> 
T Data<T, Args...>::f1() {
    return f1_impl(*this);
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-09-19
    • 2017-10-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多