小编Ami*_*rsh的帖子

'auto' 作为函数参数的模板参数占位符

C++20 允许使用auto函数参数类型。

它是否还允许auto用作函数参数类型的模板参数占位符(不相似,但在某种程度上符合C++17 template<auto>的精神)?

所以下面的代码,在 C++20 之前:

template<typename First, typename Second>
void printPair(const std::pair<First, Second>& p) {
    std::cout << p.first << ", " << p.second;
}
Run Code Online (Sandbox Code Playgroud)

可以写成:

void printPair(const std::pair<auto, auto>& p) {
    std::cout << p.first << ", " << p.second;
}
Run Code Online (Sandbox Code Playgroud)

确实可以编译并与概念的实验性 GCC 实现一起很好地工作

它是 C++20 的合法语法吗?


相关:C++ 概念的通配符说“接受这个模板参数的任何东西”

c++ templates auto c++20

25
推荐指数
1
解决办法
1424
查看次数

模板部分特化用于积分非类型参数和非积分非类型,g ++和clang之间的区别

以下是一个简单的模板部分特化:

// #1
template <typename T, T n1, T n2>
struct foo { 
    static const char* scenario() {
        return "#1 the base template";
    }
};

// #2
// partial specialization where T is unknown and n1 == n2
template <typename T, T a>
struct foo<T, a, a> { 
    static const char* scenario() {
        return "#2 partial specialization";
    }
};
Run Code Online (Sandbox Code Playgroud)

下面的主要内容在g ++(6.1)和clang ++(3.8.0)上有不同的结果:

extern const char HELLO[] = "hello";
double d = 2.3;

int main() {
    cout <<   foo<int, 1, 2> …
Run Code Online (Sandbox Code Playgroud)

c++ templates partial-specialization template-specialization

19
推荐指数
1
解决办法
400
查看次数

哪个是更专业的模板功能?clang和g ++有所不同

在使用可变参数模板时,遵循这个SO问题(注意:并不是强制要求遵循这个问题),对于以下模板重载函数,我得到了clang(3.8)和g ++(6.1)的不同行为:

template <class... Ts>
struct pack { };

template <class a, class b>
constexpr bool starts_with(a, b) {
    return false;
}

template <template <typename...> class PACK_A,
          template <typename...> class PACK_B, typename... Ts1, typename... Ts2>
constexpr bool starts_with(PACK_A<Ts1..., Ts2...>, PACK_B<Ts1...>) {
    return true;
}

int main() {
   std::cout << std::boolalpha;
   std::cout << starts_with(pack<int, float, double>(),
                            pack<float, int, double>())        << std::endl;
   std::cout << starts_with(pack<int, float, double>(),
                            pack<int, float, double, int>())   << std::endl;
   std::cout << starts_with(pack<int, float, double>(),
                            pack<int, float, …
Run Code Online (Sandbox Code Playgroud)

c++ templates overloading variadic-templates c++11

18
推荐指数
1
解决办法
404
查看次数

unordered_map 对哈希函数的过度调用

以下代码导致对哈希函数的无法解释的调用:

namespace foo {
    using Position = tuple <int, int, int>;
    
    std::ostream& operator<<(std::ostream& out, const Position& pos) noexcept{
        return out << get<0>(pos) << ", " << get<1>(pos) << ", " << get<2>(pos);
    }

    struct hashFunc{
        std::size_t operator()(const Position& pos) const noexcept{
            int res = get<0>(pos) * 17 ^ get<1>(pos) * 11 ^ get<2>(pos);
            cout << "@@@ hash function called for key: " << pos 
                 << ", hash: " << res << endl;
            return res;
        }
    };

    template<typename T>
    void print_buckets(T&& …
Run Code Online (Sandbox Code Playgroud)

c++ unordered-map

17
推荐指数
2
解决办法
326
查看次数

重载运算符&&和||的短路 在C++中17

我在http://en.cppreference.com/w/cpp/language/operators上读到:

布尔逻辑运算符,运算符&&和运算符||

与内置版本不同,重载不会在右操作数之前对其左操作数进行排序,并且(直到C++ 17)无法实现短路评估.

(我强调).

找不到C++ 17的任何资源或代码示例,支持运算符&&和operator ||的短路.它与C++ 17参数包折叠表达式有关吗?尝试使用它,但无法为重载的运算符&&和||创建短路行为 用C++ 17倍表达式.

码:

class A {
    bool val;
public:
    A(bool b) : val(b) { cout << "A born as " << boolalpha << val << endl;}
    template<typename ...Args>
    bool operator&&(Args&&... args) {
        return (val && ... && args.val);
    }    
};

int main() {
    cout << boolalpha;
    cout << ( A{false} && A{true} ) << endl;
    cout << ( A{true} && A{false} ) << endl;
    cout << ( …
Run Code Online (Sandbox Code Playgroud)

c++ operator-overloading c++17

13
推荐指数
1
解决办法
921
查看次数

编译器是否可以决定忽略 C++20 仍需要的依赖类型上缺失的类型名?

以下代码可以使用 MSVC 进行编译,但在 GCC 和 Clang 中会失败,因为typename在依赖类型之前缺少:

struct Foo { struct value{ }; };
struct Bar { int value; };

template<typename T>
constexpr size_t SIZE = sizeof(T::value); // missing typename here, for Foo

constexpr size_t s1 = SIZE<Foo>; // missing typename before dependent type above
constexpr size_t s2 = SIZE<Bar>;
Run Code Online (Sandbox Code Playgroud)

MSVC 方法不需要 typename sizeof,这似乎是合理的,因为 sizeof 对类型和变量都适用。另一方面,GCC 和 Clang 似乎按规矩办事,因为这是typename 即使在 C++20 中您仍然需要的情况之一,当上下文无法向编译器显示它是否会满足类型或多变的。

问题是这里MSVC是否允许宽容,即编译器如果不加 也能正确执行所需的操作typename,是否允许这样做?还是与规范相矛盾?


MSVC 与 Clang 和 GCC 的方法之间的差异在于以下代码 …

c++ typename language-lawyer c++20

13
推荐指数
1
解决办法
309
查看次数

std::to_array 用于多维数组

添加了 C++20 std::to_array,因此您可以轻松地从 C 样式数组创建std::array,例如:

template<typename T, std::size_t N>
void foo(const T (&a)[N]) {
    auto arr = std::to_array(a);
}
Run Code Online (Sandbox Code Playgroud)

但是,std::to_array不支持二维数组,因此以下方法不起作用:

auto arr = to_array({1, 2}, {3, 4});
Run Code Online (Sandbox Code Playgroud)

这可以手动实现吗?

c++ algorithm function-templates stdarray c++20

13
推荐指数
1
解决办法
559
查看次数

为什么右值unique_ptr的运算符*返回左值?

从“死”的unique_ptr中使用operator *的返回值是不好的。

以下代码可以编译,但是结果当然是未定义行为:

auto& ref = *std::make_unique<int>(7);
std::cout << ref << std::endl;
Run Code Online (Sandbox Code Playgroud)

为什么标准不将std :: unique_ptr 值的operator *的返回值设为内部值的值,而不是像这样的lvalue

// could have been done inside unique_ptr
T& operator*() & { return *ptr; }
T&& operator*() && { return std::move(*ptr); }
Run Code Online (Sandbox Code Playgroud)

在这种情况下,可以正常工作:

std::cout << *std::make_unique<int>(7) << std::endl;
Run Code Online (Sandbox Code Playgroud)

但是开头的代码无法编译(无法将右值绑定到左值)。


旁注:当然,有些人仍然可以像下面这样编写错误的代码,但是更冗长地说“我是UB”,因此不太相关:

auto&& ref = *std::make_unique<int>(7);
std::cout << ref << std::endl;
Run Code Online (Sandbox Code Playgroud)

是否有充分的理由让std :: unique_ptr右值上的operator *返回左值ref?

c++ undefined-behavior rvalue-reference unique-ptr c++11

11
推荐指数
2
解决办法
243
查看次数

在具有参考字段的类上放置新的

这是来自 C++20 规范 ( [basic.life]/8 )的代码示例:

struct C {
  int i;
  void f();
  const C& operator=( const C& );
};

const C& C::operator=( const C& other) {
  if ( this != &other ) {
    this->~C();              // lifetime of *this ends
    new (this) C(other);     // new object of type C created
    f();                     // well-defined
  }
  return *this;
}

int main() {    
  C c1;
  C c2;
  c1 = c2;   // well-defined
  c1.f();    // well-defined; c1 refers to a new object of type …
Run Code Online (Sandbox Code Playgroud)

c++ language-lawyer c++20 stdlaunder

11
推荐指数
2
解决办法
329
查看次数

特定类型的范围概念

在 C++20 或 range-TS 中是否有一个已经定义的概念来指定特定类型的范围?

就像是:

template < class T, class InnerType >
concept RangeOf =
  requires(T&& t) {
    requires std::same_as<
           std::remove_cvref_t<decltype(*std::ranges::begin(t))>,
           InnerType
         >;
    std::ranges::end(t);
  };
Run Code Online (Sandbox Code Playgroud)

允许,例如

void print(const RangeOf<char> auto& char_seq) { /* ... */ }
Run Code Online (Sandbox Code Playgroud)

c++ c++-concepts c++20 std-ranges

11
推荐指数
1
解决办法
1802
查看次数