小编ofo*_*ofo的帖子

类专业化中的 clang/gcc 不一致

我在尝试为C++17 中的自定义类专门化tuple_size/tuple_element以进行结构化绑定时遇到了这个问题。

下面的代码在 GCC 中编译,但不在 clang 中(两个主干版本,见下面的链接)。

#include <type_traits>

template<typename T, typename... Ts>
using sfinae_t = T;

template<typename T, bool... Bs>
using sfinae_v_t = sfinae_t<T, typename std::enable_if<Bs>::type...>;

template <typename T>
struct Test;

template <typename T>
struct Test<sfinae_v_t<T, std::is_integral_v<T>>> {};

void f() {
    Test<int> t;
}
Run Code Online (Sandbox Code Playgroud)

https://godbolt.org/z/ztuRSq

这是 clang 提供的错误:

<source>:13:8: error: class template partial specialization does not specialize any template argument; to define the primary template, remove the template argument list

struct Test<sfinae_v_t<T, std::is_integral<T>::value>> {};

       ^ …
Run Code Online (Sandbox Code Playgroud)

c++ templates partial-specialization template-specialization language-lawyer

9
推荐指数
1
解决办法
172
查看次数

具有不同概念的模板类专业化会导致重新定义错误

我正在使用std::hash一个Hashable概念编写一些代码。然而,即使我没有模糊的实例,我也无法用两个不同的概念来定义专业化。

#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 …
Run Code Online (Sandbox Code Playgroud)

c++ template-specialization c++-concepts c++20

6
推荐指数
1
解决办法
472
查看次数

range-v3:调整已经实现迭代器接口的自定义类(开始/结束)

我有一个自定义容器实现beginend. 如何将此容器通过管道传输到 range-v3 视图?

std::vector 是可管道化的,所以我尝试以相同的方式管道化我的自定义类,但找不到我的容器的管道运算符。

我查看了文档,但除了使用 Range 接口重新实现包装类之外,我找不到任何其他方法。我有多个这样的类,我相信这可能是一个相当常见的情况,所以我宁愿使用库提供的一些函数(或类库),但我无法从文档中弄清楚。

这是一个最小的例子:

#include <iostream>
#include <iterator>
#include <range/v3/all.hpp>

struct Test {
    struct iterator;
    struct sentinel {};
    int counter;
    Test() = default;
    iterator begin();
    sentinel end() const { return {}; }
    iterator begin() const;
};

struct Test::iterator {
    using value_type = int;
    using reference = int&;
    using pointer = int*;
    using iterator_category = std::input_iterator_tag;
    using difference_type = void;
    Test* test;
    iterator& operator++() {
        test->counter++;
        return *this;
    }
    iterator operator++(int) …
Run Code Online (Sandbox Code Playgroud)

c++ iterator range-v3

5
推荐指数
1
解决办法
598
查看次数

std::span 迭代器可以比创建它们的 span 对象寿命更长吗?

换句话说,反过来,std::span迭代器在span实例被销毁后会失效吗?

我有一个向量需要用不同的布局进行迭代。我试图std::span避免编写大量迭代器样板或引入外部库依赖项。简化示例:

#include <iostream>
#include <span>
#include <vector>

template <size_t N>
struct my_view {
  std::vector<int> vec;

  auto as_span() {
    return std::span<int[N]>((int(*)[N])vec.data(), vec.size() / N);
  }

  auto begin() {
    return as_span().begin();
  }

  auto end() {
    return as_span().end();
  }
};

int main() {
  std::vector vec {1, 2, 3, 4, 5, 6};
  my_view<2> pairs {std::move(vec)};
  for (auto pair : pairs) {
    std::cout << pair[0] << " " << pair[1] << std::endl;
  }
  my_view<3> triplets {std::move(pairs.vec)};
  for (auto triplet : …
Run Code Online (Sandbox Code Playgroud)

c++ iterator lifetime c++20 std-span

4
推荐指数
1
解决办法
622
查看次数

是否允许类在程序中的不同翻译单元之间具有不同的定义?

假设类在每个翻译单元中最多定义一次,在不同的翻译单元中以不同的方式定义类是否格式良好?

用例是在没有动态分配的情况下访问实现细节。C++ 代码将对已由 C 库分配的指针进行操作。

为了举例,请忽略内存泄漏。

通用文件

#pragma once

namespace Test {

class Impl;

class A {
    void *ptr;
    A(void *ptr) : ptr(ptr) {}
    friend class Impl;

   public:
    int plus_one();
};

class B {
    void *ptr;
    B(void *ptr) : ptr(ptr) {}
    friend class Impl;

   public:
    int plus_two();
};

class Factory {
   public:
    A getA(int val);
    B getB(int val);
};

}  // namespace Test
Run Code Online (Sandbox Code Playgroud)

A.cpp

#include "common.hpp"

namespace Test {

class Impl {
   public:
    static int as_int(A *a) { return *static_cast<int …
Run Code Online (Sandbox Code Playgroud)

c++ one-definition-rule linkage

3
推荐指数
1
解决办法
74
查看次数