简体   繁体   English

具有编译时间常数的模板专业化

[英]Template specialization with compile time constant

I am trying to build a specialization for a template class with a compile time constant. 我正在尝试为具有编译时间常数的模板类建立专门化的版本。

The template class looks like this: 模板类如下所示:

template<class TNativeItem, class TComItem = void,
         VARTYPE _vartype = _ATL_AutomationType<TComItem>::type>
class InOutComArray
{
private:
    CComSafeArray<TComItem, _vartype> _safeArray;
    // ...
public:
    InOutComArray(
        TNativeItem* items, size_t length,
        std::function<TComItem(const TNativeItem&)> convertToCom,
        std::function<TNativeItem(const TComItem&)> convertFromCom)
        : _safeArray(length)
    {
        // ...
    }

    // ...
};

Usage would be for example: 用法例如:

InOutComArray<BOOL, VARIANT_BOOL, VT_BOOL>(
    items, length, BOOLToVARIANT_BOOL, VARIANT_BOOLToBOOL));

However, there also exist types that don't require conversion and I wanted to provide a short hand version for this: 但是,也有一些类型不需要转换,我想为此提供一个简短的版本:

InOutComArray<LONG>(items, length);

I tried to implement it like this: 我试图这样实现:

template<class TItem, VARTYPE _vartype = _ATL_AutomationType<TItem>::type>
class InOutComArray<TItem, void, _vartype>
    : public InOutComArray<TItem, TItem, _vartype>
{
public:
    InOutComArray(TItem* items, size_t length)
        : InOutComArray<TItem, TItem, _vartype>(
              items, length, NoConverter<TItem>, NoConverter<TItem>)
    {

    }
};

However, I get the following error: 但是,出现以下错误:

'_vartype' : default template arguments not allowed on a partial specialization '_vartype':部分专门化不允许使用默认模板参数

Is there any way around that? 有什么办法解决吗?

You first define the default arguments to be void and _ATL_AutomationType<TComItem>::type , so when exactly one argument X is given, you want InOutComArray<X> to be an InOutComArray<X, void, _ATL_AutomationType<void>::type> . 首先,将默认参数定义为void_ATL_AutomationType<TComItem>::type ,因此,当给出一个正好为X的参数时,您希望InOutComArray<X>成为InOutComArray<X, void, _ATL_AutomationType<void>::type>

Your partial specialization contradicts this: InOutComArray<X> shall be a InOutComArray<X, X, _ATL_AutomationType<X>::type> . 您的部分专业化与此矛盾: InOutComArray<X>应该是InOutComArray<X, X, _ATL_AutomationType<X>::type>

Depending on what you thik will be more likely second argument, (ie void or the same as the first argument), you could make the second argument defaulted to the first one in the first place: 根据您认为第二个参数(即void或与第一个参数相同)的不同,可以将第二个参数默认设置为第一个参数:

template<class TNativeItem, class TComItem = TNativeItem,
     VARTYPE _vartype = _ATL_AutomationType<TComItem>::type>

That way the behavior of the partial specialization is covered, except for the additional constructor. 这样,除了额外的构造函数之外,还涵盖了部分专业化的行为。 This can be achieved by using default arguments for the constructor: 这可以通过使用构造函数的默认参数来实现:

template<class TNativeItem, class TComItem = TNativeItem,
     VARTYPE _vartype = _ATL_AutomationType<TComItem>::type>
class InOutComArray
{
public:
InOutComArray(
    TNativeItem* items, size_t length,
    std::function<TComItem(const TNativeItem&)> convertToCom = NoConverter<TNativeItem>(),
    std::function<TNativeItem(const TComItem&)> convertFromCom = NoConverter<TNativeItem>());
};

According to the standard §14.5.5/8 Class template partial specializations [temp.class.spec]: 根据标准§14.5.5/ 8类模板的部分专业化[temp.class.spec]:

The template parameter list of a specialization shall not contain default template argument values. 专业化的模板参数列表不应包含默认模板参数值。

Thus, the compiler rightfully complains because in your partial specialization you give default template argument value for VARTYPE _vartype = _ATL_AutomationType<TItem>::type . 因此,编译器理应抱怨,因为在您的部分专业化工作中,您为VARTYPE _vartype = _ATL_AutomationType<TItem>::type提供了默认模板参数值。

Is there any way around that? 有什么办法解决吗?

Yes, remove the default template argument from the partial specialization. 是的,从部分专业化中删除默认模板参数。 You don't need it. 不用了

Per the primary template: 根据主要模板:

template<class TNativeItem, class TComItem = void,
         VARTYPE _vartype = _ATL_AutomationType<TComItem>::type>
class InOutComArray

These types are equivalent: 这些类型是等效的:

InOutComArray<LONG>
InOutComArray<LONG, void, _ATL_AutomationType<TComItem>::type>

And whenever InOutComArray is instantiated with TComItem = void , you will get the partial specialization: 每当InOutComArray与实例TComItem = void ,你会得到部分特:

template<class TItem, VARTYPE _vartype>
class InOutComArray<TItem, void, _vartype>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM