22

鉴于:

struct A
{
    virtual bool what() = 0;
};

template<typename T, typename Q>
struct B : public A
{
    virtual bool what();
};

我想部分专业化what,例如:

template<typename T, typename Q>
bool B<T, Q>::what()
{
    return true;
}

template<typename Q>
bool B<float, Q>::what()
{
    return false;
}

但似乎这是不可能的(是在 C++11 中吗?)所以我尝试了 SFINAE:

template<typename T>
typename std::enable_if<std::is_same<T, float>::value, bool>::type B<T>::what()
{
    return true;
}

template<typename T>
typename std::enable_if<!std::is_same<T, float>::value, bool>::type B<T>::what()
{
    return false;
}

这也不起作用,我不知道为什么,有人吗?所以我找到了这个线程并最终得到:

template<typename T, typename Q>
struct B : public A
{
    virtual bool what()
    {
        return whatimpl(std::is_same<T, float>());
    }

    bool whatimpl(std::false_type)
    {
        return false;
    }

    bool whatimpl(std::true_type)
    {
        return true;
    }
};

这个最终解决方案有效,但为什么该enable_if技术不起作用?我也非常愿意接受我尚未遇到的更简洁答案的建议。

我尽可能地简化了我的例子——在我的真实用例what()中不叫什么,实际上做了很多工作,我想“专门化”一个用户定义的类型,而不是float.

4

3 回答 3

13

标准仅对类模板明确允许部分特化(参见 14.5.5 类模板部分特化)

对于类模板的成员,只允许显式特化。

14.7 (3) 说:

可以为函数模板、类模板、类模板的成员或成员模板声明显式特化。template<>引入了显式的特化声明。

所以任何以

template<typename T>  

不是类模板特化成员允许的语法。

[编辑]

至于 SFINAE 的尝试,它失败了,因为实际上这里既没有重载也没有特化(SFINAE 在为重载解决方案定义一组候选函数或选择适当的特化时工作)。what() 被声明为类模板的单个方法并且应该有一个定义,并且这个定义应该有一个形式:

template<typename T, typename Q> 
B<T,Q>:: bool what(){...}

或者也可以明确专门用于 B 类的特定实例化:

template<> 
B<SomeParticularTypeT,SomeParticularTypeTypeQ>:: bool what(){...}

任何其他形式在语法上都是无效的,所以 SFINAE 无能为力。

于 2012-04-24T08:02:31.677 回答
1

为什么不改成..

template<typename T, typename Q> 
struct B : public A 
{   
   bool what()
   {
      return false; //Or whatever the default is...
   }
}; 

template<typename Q>
struct B<float, Q> : public A 
{   
   bool what()
   {
      return true;
   }
}; 
于 2012-04-23T20:01:33.047 回答
0

根据您的用例,两种可能的解决方案:

  1. 灵活的实现类:您的方法的一个问题是类型缺乏灵活性 - 不超过 true 或 false 类型。基于这个出色的CppCon 演讲(幻灯片 77),我通过将工作委托给另一个特定于实现的类模板编写了这个解决方案。您可以在此处查看并运行此代码。这种方法的缺点是我无法访问其余的类成员,但可以将它们传入。
  2. 操纵 Enable If:我还没有完全理解为什么您的 enable_if 解决方案不起作用,但这是我的,它正在起作用。它使您可以部分地专注于课程本身。

PS 我想直接在此处添加代码,但存在一些格式问题。如果有人可以帮助我添加来自 Coliru 的格式化代码,那就太好了。

于 2018-09-18T16:50:29.393 回答