【问题标题】:MSVC 2015 choosing incorrect constructor overload for std::vectorMSVC 2015 为 std::vector 选择不正确的构造函数重载
【发布时间】:2016-07-07 17:39:27
【问题描述】:

以下是我的矩阵类的一部分,它具有动态的行数和列数,该类使用std::vector 以行优先顺序存储矩阵元素。


dynamic_matrix

template<typename _Ty,
    class _Alloc = std::allocator<_Ty>
> class dynamic_matrix {
public:
    typedef _Ty value_type;
    typedef std::size_t size_type;
    typedef _Alloc allocator_type;
    // various other typedefs, not relevant here...
    explicit dynamic_matrix(size_type _rows, size_type _cols, const _Alloc& alloc = _Alloc())
        : mtx(_rows*_cols, alloc), rows_(_rows), cols_(_cols) {}
    explicit dynamic_matrix(size_type _rows, size_type _cols, const value_type& _val,
        const _Alloc& alloc = _Alloc()) : mtx(_rows*_cols, _val, alloc), rows_(_rows), cols_(_cols) {}
    // other constructors and methods omitted...
private:
    std::vector<_Ty, _Alloc> mtx;
    size_type rows_;
    size_type cols_;
};

当我尝试使用上面显示的 sn-p 中的第一个构造函数和以下测试构造 dynamic_matrix 时,

int main(void) {
    dynamic_matrix<int> dm(10,10);
}

我从MSVC 2015 收到以下错误:

std::vector<_Ty,_Alloc>::vector(std::initializer_list<int>,const std::allocator<_Ty>&)
: cannot convert argument 2 from 'const std::allocator<_Ty>' to 'const int&'

而在GCC 6.1.0 中使用以下命令编译它不会产生警告或错误,

g++-6.1.0 --std=c++14 -Wall -pedantic -o maintest main.cpp dynamic_matrix.h

在上面的 dynamic_matrix 代码 sn-p 中使用第二个构造函数可以很好地编译 GCC 和 MSVC。

问题似乎是 MSVC 出于某种原因将构造函数调用 mtx(_rows*_cols, alloc) 解释为来自此 reference 的第 7 个构造函数,这将解释 cannot convert from const std::allocator to const int&amp; 错误消息。而 GCC 似乎按照我的意图使用了上述参考中的第三个构造函数。

为什么 MSVC 没有选择正确的构造函数来从 std::vector 调用而 GCC 是,我可以做些什么来缓解这种情况?

【问题讨论】:

  • 如果你改用mtx{_rows*_cols, alloc}会发生什么?
  • 恐怕仍然会出现同样的错误。
  • 如果分配器对您来说不是那么重要,如果您忽略它,它就会起作用。
  • 实际上...如果我查看 MSVC 中的 STL 源代码,我看不到一个接受计数和分配器的构造函数。我可能会误解这一点,但我认为您尝试使用的构造函数在 MSVC 中根本不存在,无论是否偶然。但是,有一个用于计数、填充值和分配器的构造函数,因此您可以考虑使用它。

标签: c++ gcc visual-c++


【解决方案1】:

状态更新

该错误已修复并在 VS 2015 Update 3 中发布


查看 MSVS 中的矢量头,没有带有表单的构造函数

explicit vector( size_type count, const Allocator& alloc = Allocator() )

但它确实有

explicit vector(size_type _Count)

这是一个 C++11 添加的构造函数,在 C++14 中更改为以前的构造函数。看来 MSVS 还没有跟上这种变化。

真正奇怪的是vector&lt;bool&gt; 的特化确实在头文件中有正确的构造函数,如果你使用

dynamic_matrix<bool> dm(10, 10);

它会编译。

我已经向 MS 提交了错误报告,您可以看到它here

在解决此问题之前,您可以使用以下形式的构造函数

vector( size_type count, 
             const T& value,
             const Allocator& alloc = Allocator());

并提供一个值来构造元素。

【讨论】:

  • 我明白了,感谢您的错误报告 - 我本以为 MS 现在已经应用了此更改。
  • @ArchbishopOfBanterbury 这里也是。它一定被忽略了/有人检查了它但忘了做这项工作;)
  • @ArchbishopOfBanterbury 添加了一个可能的解决方法。
  • 是的,这行得通,我可以使用该构造函数并将值默认初始化为第二个参数。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-12-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-11-03
相关资源
最近更新 更多