【问题标题】:C++ constness on template type parameter模板类型参数上的 C++ 常量
【发布时间】:2016-05-04 12:20:05
【问题描述】:

我正在使用标准容器,例如 vector 和 pair,使用自定义类型作为模板参数。大多数情况下,这些模板类型是 const 限定的,如:

std::vector<const std::pair<const customType, const double>>

已经定义了Hash()运算符和比较运算符==和

当我将这些值传递给标准库函数(如 partial_sort_copy、partial_sort 和擦除)时,就会出现问题。出于某种原因,这些函数最终会尝试对给定类型进行分配,最终由于 const 导致编译失败。

有没有办法将 const 转换为 vector 和 pair 的模板类型?即,将vector&lt;const myType&gt; 转换为vector&lt;myType&gt;

提前致谢。

编辑:现在最小示例代码有冲突!

// Non-working code:
std::vector<const std::pair<const int, const double>> list{ { 3, 3. }, { 2, 2. }, { 1, 1. }, { 0, 0. } };
std::partial_sort(list.begin(), list.begin() + 2, list.end(), [](const std::pair<const int, const double>& x, const std::pair<const int, const double>& y){ return x.first < y.first; });

// This works, actually:
std::vector<std::pair<int, double>> list{ { 3, 3. }, { 2, 2. }, { 1, 1. }, { 0, 0. } };
std::partial_sort(list.begin(), list.begin() + 2, list.end(), [](const std::pair<int, double>& x, const std::pair<int, double>& y){ return x.first < y.first; });

标准库不喜欢我的代码的哪些方面?

【问题讨论】:

  • 您可能应该使用非常量的 const 值对。也许定义一个 ADL 可用的 swap 会有所帮助,但您必须继承 std::pair,因为在 std 中定义任何内容都不是一个好主意。
  • 感谢您的回答。我会查一下 ADL。
  • @bipll 完全允许在 std 命名空间中定义函数重载/模板,如 swaphash
  • 其实我是在 hash 的 operator() 的情况下这样做的
  • @Johan,但 std::swap 没有被 ADL 捕获,嗯?

标签: c++ templates vector constants std-pair


【解决方案1】:

这种 const 类型的容器是未定义的行为。 std::vector&lt;const T&gt; 使用 std::allocator&lt;const T&gt; 作为其分配器类型,并且分配器要求规定值类型必须是非常量对象类型。

即使忽略...

有没有办法将 const 转换为向量和对的模板类型?即,将vector&lt;const myType&gt; 转换为vector&lt;myType&gt;

没有。

一般some_template&lt;T&gt;some_template&lt;const T&gt; 是完全不相关的类型,所以你不能在它们之间进行转换。与const some_template&lt;T&gt;some_template&lt;T&gt; 不同,它们之间没有有效的转换。

所以你应该停止使用 const 对象的向量。而是使用非常量对象的 const 向量。

【讨论】:

  • 嗯。终于有事了。那么,如果模板化类型的行为未定义,为什么允许我对它们使用此类 const 约束呢?我还注意到,虽然 const myType const * 是有效类型,但将其用于向量类型被视为重复的 const 限定符。这是否与我陈述的问题有关?谢谢!
  • @jvier const T*T const* 是相同的类型。你可能指的是const T* const(注意星号后面的const)。
  • @jvier "undefined behavior" 表示不允许这样做,但允许编译器不给出任何警告信息
  • @milleniumbug。你是对的。我搞砸了。感谢您指出。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-07-09
  • 2023-03-31
  • 1970-01-01
  • 2014-10-03
相关资源
最近更新 更多