简体   繁体   English

基于 class 模板参数专门化 C++ 成员 function

[英]Specialize C++ member function based on class template argument

I have a class with a template parameter which should decide which of two styles of data it contains.我有一个带有模板参数的 class 应该决定它包含的两个 styles 数据中的哪一个。 Based on that parameter I want to implement a member function one of two different ways.基于该参数,我想实现成员 function 两种不同方式之一。 I tried using Boost Enable-If, but without success.我尝试使用 Boost Enable-If,但没有成功。 Here's the version of the code that I'm most surprised doesn't work:这是我最惊讶的代码版本不起作用:

#include <boost/utility/enable_if.hpp>
enum PadSide { Left, Right };
template <int> struct dummy { dummy(int) {} };

template <PadSide Pad>
struct String
{
    typename boost::enable_if_c<Pad ==  Left, void>::type
        getRange(dummy<0> = 0) {}
    typename boost::enable_if_c<Pad == Right, void>::type
        getRange(dummy<1> = 0) {}
};

int main()
{
    String<Left> field;
    field.getRange();
}

To this, g++ 4.6.0 says:对此,g++ 4.6.0 说:

no type named ‘type’ in ‘struct boost::enable_if_c<false, void>’

Of course, the second overload is supposed to not work, but it's supposed to be ignored due to SFINAE.当然,第二个重载应该不起作用,但由于 SFINAE,它应该被忽略。 If I remove the dummy function parameters, g++ says this:如果我删除虚拟 function 参数,g++ 会这样说:

‘typename boost::enable_if_c<(Pad == Right), void>::type
    String<Pad>::getRange()‘
cannot be overloaded with
‘typename boost::enable_if_c<(Pad == Left), void>::type
    String<Pad>::getRange()‘

Which is why I put the dummy parameters there in the first place--following the Compiler Workarounds section of the documentation .这就是为什么我将虚拟参数放在首位的原因——遵循文档的编译器解决方法部分。

Basically what I want is to have two implementations of getRange(), and have one or the other be selected based on the Pad type.基本上我想要的是有两个 getRange() 实现,并根据 Pad 类型选择一个或另一个。 I was hoping that Enable-If would let me do it without making auxiliary classes to delegate the work to (which I'm going to try in the meantime).我希望 Enable-If 能让我做到这一点,而无需制作辅助类来委派工作(我将同时尝试)。

Since you are going to be making two different versions of getRange() anyways, you can always overload your struct String member functions depending on the type of PadSide .由于无论如何您都将制作两个不同版本的getRange() ,因此您始终可以根据PadSide的类型重载struct String成员函数。 I know it's not as "pretty", but in the end, it's still a similar amount of code, and you won't have to make multiple class types.我知道它不是“漂亮”,但最后,它仍然是相似数量的代码,并且您不必制作多个 class 类型。

template<PadSide Pad>
struct String
{
    void getRange();
};

template<>
void String<Right>::getRange() { /*....*/ }

template<>
void String<Left>::getRange() { /*....*/ }

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

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