【问题标题】:template type deduction in a member function of a templated class模板类的成员函数中的模板类型推导
【发布时间】:2020-04-25 22:35:15
【问题描述】:

main函数第一行推演失败,不加额外模板参数如何解决

#include <iostream>

template <typename T>
class myVec{
    size_t _size{};
    size_t capacity{};
    T* data{};

public:
    myVec(size_t size = 0, T value = T{}):_size{size}, capacity{2 * _size}{
        data = new T[capacity];
        for(size_t index{}; index < _size; index++)
            data[ index ] = T{};
    }

    template <typename ... Ts>
    myVec( Ts&& ... vals):myVec{ sizeof...(vals)}{


        size_t index{};
        ((data [ ++index ] = vals),...);
    }

    ~myVec(){
        delete[] data;
    }
    size_t size( ){
        return _size;
    }
    /*the rest */

};

int main(){
    myVec vec {1, 32, 5, 6};

    for(size_t index{}; index < vec.size(); ++index )
        std::cout << vec[ index ] << " ";
}

【问题讨论】:

  • 你希望该行调用什么构造函数?
  • @cigien 对不起。见编辑
  • myVec&lt;int&gt;(size_t{5}) 创建一个包含五个0s 的向量,myVec&lt;int&gt;(5) 创建一个包含一个5 的向量。那是……微妙的。
  • @Barry 让我想起了统一初始化,只是没有大括号

标签: c++ c++17 variadic-templates type-deduction


【解决方案1】:

类模板只有在与构造函数完全匹配时才能隐式推导出类模板参数,例如:

template <typename T>
class myVec
{
    ...
    myVec(int, T); // T can be deduced since it's from the class template
    ...
};
...
myVec(5,5); // deduces myVec<int>

另一方面,构造函数模板中的类型不直接参与推导——因为推导的类型不一定与类模板的类型相同:

template <typename T>
class myVec
{
    ...
    template <typename U>
    myVec(int, U); // U may not be the same as T!
    ...
    template <typename...Ts>
    myVec(Ts&&...); // All 'Ts' types may not be the same as 'T'
    ...
};

解决此问题的方法是使用user-defined deduction guides。这些允许您定义在面对其他模棱两可的构造函数表达式时推导出的类型。在您的情况下,您可能正在寻找类似的东西:

template <typename...Ts> 
myVec(Ts...) -> myVec<std::common_type_t<Ts...>>;

注意: std::common_type_t 用于获取所有可变参数类型的公共类型。它在&lt;type_traits&gt; 标头中定义。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-02-21
    • 2011-07-06
    相关资源
    最近更新 更多