【问题标题】:Template class specialization with different concepts gives redefinition error具有不同概念的模板类专业化会导致重新定义错误
【发布时间】:2021-08-22 22:47:45
【问题描述】:

我正在使用std::hashHashable 概念编写一些代码。但是,即使我没有它们的模棱两可的实例,我也无法用两个不同的概念来定义专业化。

#include <ranges>
#include <concepts>
#include <functional>

namespace ranges = std::ranges;

template <typename T>
concept Hashable = requires(const T& t) {
  { std::hash<T>{}(t) } -> std::convertible_to<size_t>;
};

template <typename T>
concept HashableWithMember = requires(const T& t) {
  { t.Hash() } -> std::convertible_to<size_t>;
};

template <typename R>
concept HashableRange = ranges::range<R> && Hashable<ranges::range_value_t<R>>;

template <HashableWithMember T>
struct std::hash<T> {
  size_t operator()(const T& t) const { return t.Hash(); }
};

template <HashableRange R>
struct std::hash<R> {
  size_t operator()(const R& r) const {
    return 0;
  }
};

template <Hashable T>
static size_t Hash(const T& t) {
  return std::hash<T>{}(t);
}
<source>:26:13: error: redefinition of 'struct std::hash<_Tp>'
   26 | struct std::hash<R> {
      |             ^~~~~~~
<source>:21:13: note: previous definition of 'struct std::hash<_Tp>'
   21 | struct std::hash<T> {
      |             ^~~~~~~

https://godbolt.org/z/1roj1qMbs

如果有一个既是 HashableRangeHashableWithMember 的类,我会理解这个错误,但没有。为什么这不起作用?

【问题讨论】:

  • 好像是bug
  • 我想是的。再看一遍,我意识到如果我在明确的 namespace std 中包含专业化它是有效的:godbolt.org/z/h9811vEEe 罪魁祸首似乎是用 struct std::hash 语法来专门化它们。

标签: c++ c++20 template-specialization c++-concepts


【解决方案1】:

这是已知的 GCC 错误 [concepts] redefinition error when using constrained structure template inside namespace: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=92944

一个更简单的例子如下:

#include <concepts>
#include <functional>

template <std::convertible_to<int> T>
struct std::hash<T> {};

template <std::convertible_to<float> U>
struct std::hash<U> {};

Clang 和 MSVC 都可以,这个 bug 只是 GCC。演示:https://gcc.godbolt.org/z/Warhfaf7q

【讨论】:

    猜你喜欢
    • 2021-09-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-10-21
    相关资源
    最近更新 更多