c++ - std::array<const T, n> 与 std::array<T, n> 重载解析

标签 c++ arrays templates c++14 c++17

这个问题看起来很简单,但我只能用“丑陋”的方式解决它。这是一个简短的代码:

#include <array>
struct A {
    A(int , int = 0) {}
    A(std::array<const int, 2>) {}
    //A(std::array<int, 2>) {}
};

int main(){
    std::array<int, 2> a = {0};
    const A x(a);
    return 0;
}

按原样,编译器正在尝试使用 A(int, int = 0)构造函数,当然,失败了 std::arrayint转换。

注释掉第一个构造函数会给出一个明显的编译器错误 std::array<int, 2>不能自动转换成它的 const 对应物。这让我有些困惑,因为我认为非常量到 const 的转换是“微不足道的”。

通过引入第三个构造函数(在代码示例中注释掉)解决了这个问题,但这看起来有点矫枉过正。

我的问题是:

  1. 为什么这里没有自动完成非常量到常量的转换?
  2. 是否可以在不引入构造函数的第三个非常量版本的情况下“修复”这个问题?
  3. 更改构造函数以接受 gsl::span而不是 std::array也有帮助,但也感觉有点矫枉过正

我正在使用 C++17 设置在 MSVC 2017 15.7.4 上进行编译。

最佳答案

1) Why is the non-const to const conversion not done automatically here?

因为 std::array<T, Dim> conststd::array<T const, Dim>是不同的类型,我的 clang++ 怎么说,“没有已知的从‘array<int, [...]>’到‘array<const int, [...]>’的转换”

2) Can this be "fixed" without introducing the third, non-const version of the constructor?

模板构造器呢

template <typename T>
A (std::array<T, 2> const &) {}

哪里T可以同时匹配 intint const

如果你想强加 T只有intint const (而不是,例如,long const)你可以通过 SFINAE 来做这件事

template <typename T>
A (std::array<T, 2>,
   std::enable_if_t<std::is_same<T const, int const>{}> * = nullptr)
 { }

所以你可以拥有

std::array<int, 2> a = {{0}};
std::array<int const, 2> b = {{0}};
std::array<long const, 2> c = {{0}};

const A x(a);  // compile
const A y(b);  // compile
const A z(c);  // compilation error

3) Changing the constructor to accept gsl::span instead of std::array also helps, yet also feels like an overkill as well

抱歉,我不明白第三个问题(?)(我也不知道 gls::span )

关于c++ - std::array<const T, n> 与 std::array<T, n> 重载解析,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51053742/

相关文章:

c - GTK+ 中基于模板的 UI 的优点是什么

c++ - 如何从 C++/MFC 程序中获取控制台窗口?

c++ - 临时对象混淆

c++ - qt4 designer 添加自定义类

php - 通过引用修改数组

C++模板类

c++ - 这个来自 Effective Modern C++ 的项目仍然是最新的吗?

Android:在 ImageView 中显示图像数组

java - 随机对象和数组

c++ - "template polymorphism"为基类型的模板化参数调用函数时,具有派生类型?