[用于模板化基类的C ++函数模板专业化

问题描述 投票:2回答:1

我正在尝试为模板化类和所有派生子级实现成员函数模板专业化。它适用于班级本身,但不适用于孩子。

请看下面的示例演示问题:

#include <vector>

struct MyVector : public std::vector<int> {};

struct S {
    template <typename T>
    int make(T value) {
        return 1;
    }

    template <typename T>
    int make(const std::vector<T>& value) {
        return 2;
    }
};

int main() {
    S s;
    // return s.make(std::vector<int>{}); // returns 2, perfekt!
    return s.make(MyVector{}); // returns 1 but should return 2
}

实时:https://godbolt.org/z/PgYkKf

我在stackoverflow上搜索了几个小时,但是找不到合适的解决方案。我感谢任何提示!

c++ sfinae template-specialization
1个回答
3
投票

功能模板专业化

第一笔订单。这不是专业。重要的是要解决这个问题。这太重了。这两个功能模板使make名称超载。过载解析可以在综合其签名后确定哪个更匹配。在您的情况下,编译器可以推断出的两个签名是

int make(MyVector);
int make(std::vector<int> const&);

[一个是身份转换,而另一个则是将引用绑定到一个基数,就转换而言,该基数比“身份”差。这样就选择了第一个重载。

您之前有几个选择:

  1. 首选类型别名,例如using MyVector = std::vector<int>;。它向前发展,完全匹配第二个重载,并且由于功能模板的部分排序而使其被选择。

  2. 添加MyVector重载,代表:

    int make(MyVector const& v) { return make(static_cast<MyVector::vector const&>(v)); }
    
  3. 使用更复杂的技术来控制重载分辨率。标准库具有一些用于基于SFINAE的过程控制的实用程序。这将需要将第一个重载更改为此:

    template <typename T>
    std::enable_if_t<!std::is_convertible_v<T*, std::vector<int>*>, int>
    make(T value) {
        return 1;
    }
    

    但是此方法过于专家友好,并且不会因许多模板重载而迅速扩展。我首先建议使用前两种方法。


0
投票

功能模板专业化

第一笔订单。这不是专业。重要的是要解决这个问题。这太重了。这两个功能模板使make名称超载。过载解析可以在综合其签名后确定哪个更匹配。在您的情况下,编译器可以推断出的两个签名是

int make(MyVector);
int make(std::vector<int> const&);

[一个是身份转换,而另一个则需要将引用绑定到基数,就转换而言,该基数比“身份”差。这样就选择了第一个重载。

您之前有几个选择:

  1. 首选类型别名,例如using MyVector = std::vector<int>;。它向前发展,完全匹配第二个重载,并且由于功能模板的部分排序而使其被选择。

  2. 添加MyVector重载,代表:

    int make(MyVector const& v) { return make(static_cast<MyVector::vector const&>(v)); }
    
  3. 使用更复杂的技术来控制重载分辨率。标准库具有一些用于基于SFINAE的过程控制的实用程序。这将需要将第一个重载更改为此:

    template <typename T>
    std::enable_if_t<!std::is_convertible_v<T*, std::vector<int>*>, int>
    make(T value) {
        return 1;
    }
    

    但是此方法过于专家友好,并且不会因许多模板重载而迅速扩展。我首先建议使用前两种方法。

© www.soinside.com 2019 - 2024. All rights reserved.