标签: c++23

“if consteval”提案文件中的“SSE 4.2 insanity”是什么意思?

我正在阅读一篇关于if consteval (\xc2\xa73.2)的 C++ 论文,并看到一段显示constexpr strlen实现的代码:

\n
constexpr size_t strlen(char const* s) {\n    if constexpr (std::is_constant_evaluated()) {\n        for (const char *p = s; ; ++p) {\n            if (*p == \'\\0\') {\n                return static_cast<std::size_t>(p - s);\n            }\n        }    \n    } else {\n        __asm__("SSE 4.2 insanity");        \n    }\n}\n
Run Code Online (Sandbox Code Playgroud)\n

我是来询问__asm__else分支中的语句的。

\n

我知道这是幽默,并不意味着要认真对待,但我仍然决定做一些研究,以防有人已经解释过。\n当我用谷歌搜索引用的消息时,我得到的结果不到 10 个,全部都是关于这段代码的.\n然后我研究了什么是SSE 4.2,发现它是一个CPU指令集,所以我真的不知道它在C++论文中出现的内容,有人有解释吗?\n感谢那些会阅读的人我的帖子。

\n

c++ sse sse4 c++23

2
推荐指数
1
解决办法
229
查看次数

根据“auto(x)”论文(wg21.link/p0849),为什么“return std::forward&lt;T&gt;”无法完美转发用“T&amp;&amp;”输入的参数?

auto (x)表达式已添加到语言中。理性是因为我们无法以此完善前向衰减。

template<class T>
constexpr decay_t<T> decay_copy(T&& v) noexcept(
    is_nothrow_convertible_v<T, decay_t<T>>) {
    return std::forward<T>(v);
}
Run Code Online (Sandbox Code Playgroud)

decay_copy根据论文https://wg21.link/p0849 ,这只是无法避免复制。

一个明显的问题是,decay_copy(x.front())副本x.front()即使x.front()是一个prvalue,换句话说,是一个副本。


是否应该std::forward<T>完美转发使用通用/转发引用声明的输入参数?

c++ type-traits perfect-forwarding auto c++23

2
推荐指数
1
解决办法
93
查看次数

使用概念区分一维和二维容器

我想使用概念来区分一维和二维容器。我的第一次尝试如下:

template<typename C>
concept Container1D = requires(C c) {
    std::begin(c);
    std::end(c);
    c[0];
};

template<typename C>
concept Container2D = requires(C c) {
    std::begin(c);
    std::end(c);
    c[0, 0]; // interpreted as comma-operator
};
Run Code Online (Sandbox Code Playgroud)

但显然这不起作用,因为表达式0, 0被解释为逗号运算符,因此第二个概念也匹配一维容器。

有没有办法要求二维operator[a, b]

c++ containers concept c++23

2
推荐指数
1
解决办法
76
查看次数

如何从 std::chunk_by 返回值获取各个块?

我有以下 c++23 代码,它使用gcc-13.2.

#include <iostream>
#include <ranges>
#include <vector>

auto main() -> int
{
    using std::cout;
    std::vector<int> v{1,2,2,2,1,1,1,2,1};
    auto chunks = v | std::views::chunk_by(std::equal_to{});
    for (auto chunk : chunks)
    {
        cout << "[";
        for (const auto& value : chunk)
        {
            cout << value << ", ";
        }
        cout << "]\n";
    }
    cout << std::flush;
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

打印

[1, ]
[2, 2, 2, ]
[1, 1, 1, ]
[2, ]
[1, ]
Run Code Online (Sandbox Code Playgroud)

正如预期的那样。

但我只想获取该列表 ( [2, 2, 2, …

c++ std-ranges c++23

2
推荐指数
1
解决办法
93
查看次数

为什么概念要求没有生效

在以下代码中,它在 -std=c++23 标志下编译。为什么概念要求 In 参数不应被引用触发?

#include <concepts>
#include <type_traits>
#include <functional>

template <typename T>
concept NotRef = requires { !std::is_reference_v<T>; };

template <typename In, typename Out>
    requires NotRef<In> // requires that In should not be reference
class SwitchType
{
    using ConstIn = std::add_const_t<In>;
public:
    SwitchType(const In& in)
        : in_{in}
    { }
    ConstIn & in_;
};

int main()
{
    int a{9};
    // Expected behavior: 'requirement not satifsfied'
    // Actural behavior: compiles under c++ 23

    SwitchType<int&, int> mytype{a};
}
Run Code Online (Sandbox Code Playgroud)

c++ c++-concepts c++23

2
推荐指数
1
解决办法
97
查看次数

C++23 悬空引用编译错误

以下显然会导致 C++23 中的编译错误:

int& f(int& x) {
    int y = ++x;
    return y;
}
Run Code Online (Sandbox Code Playgroud)

错误cannot bind non-const lvalue reference of type 'int&' to an rvalue of type 'int'

但这似乎没有给我们一个警告:

int& f(int x) {
    int &y = ++x;
    return y;
}
Run Code Online (Sandbox Code Playgroud)

这在编译阶段是不是更难捕捉?

谢谢。

c++ reference c++23

2
推荐指数
1
解决办法
176
查看次数

为什么在函数指针中使用显式对象参数会出现语法错误?

因此,在我正在处理的项目中尝试对函数指针使用显式对象参数时,我遇到了问题。乍一看,代码在语法上似乎很好,但由于这是一个新功能,我在网上找不到太多信息,所以我不知道为什么会出现随机语法错误。具体来说,错误是“语法错误:')'”

我唯一真正的猜测是,这是某种 MSVC 不完整性/错误,在这种情况下我可能不得不切换到不同的编译器。

///base.h
///...
#include <map>

template <class s>
using FunctionMap = std::map<std::string,void(*)(this s& self)>;
                                            ///^ Syntax Error Here

class base{
//...
public:
   ///Get Map of fPtr
   template <class Self>
   FunctionMap<Self>* get_scripts(this const Self& self);
}
Run Code Online (Sandbox Code Playgroud)

我预计它可以编译,但它不断出现语法错误。我知道显式对象参数仅在 MSVC 中部分实现。

c++ visual-c++ c++23 explicit-object-parameter

2
推荐指数
1
解决办法
142
查看次数

如何使用 chrono::parse 向流写入/读取 std::chrono::zoned_seconds ?

我正在尝试将一个chrono::zoned_seconds对象作为文本写入文件,然后检索它并chrono::zoned_seconds稍后构造另一个对象。如何才能以相当有效的方式完成此任务?

我认为下面的代码片段没有显示正确的结果:

#include <fstream>
#include <print>
#include <chrono>
#include <format>
#include <string>
#include <sstream>


int main()
{
    {
        std::ofstream file("data.txt");
        if (!file) {
            std::println( "Unable to open file.\n" );
            return 1;
        }

        auto now = std::chrono::system_clock::now();
        const std::chrono::zoned_seconds zs { "America/New_York", std::chrono::time_point_cast<std::chrono::seconds>( now ) };

        std::format_to(std::ostreambuf_iterator<char>(file), "{:%F %T %Z}", zs);
        std::println( "{:%F %T %Z}", zs ); // correct time
    }

    {
        std::ifstream file("data.txt");
        if (!file) {
            std::println( "Unable to open file.\n" );
            return 1;
        }

        std::string …
Run Code Online (Sandbox Code Playgroud)

c++ fstream datetime-format c++-chrono c++23

2
推荐指数
1
解决办法
32
查看次数

如何部分专门化 std::hash 模板?

假设我们有一段代码如下

#include <list>
#include <string>
#include <unordered_map>

int main() {
    std::list<int> myList = {4, 1, 3, 2};
    std::unordered_map<std::list<int>::iterator, std::string> myMap;
    myMap[myList.begin()] = "first element";
}
Run Code Online (Sandbox Code Playgroud)

这段代码本身不起作用,因为我们必须为 定义一个模板专门化std::hash,如下所示

template<>
class std::hash<std::list<int>::iterator> {
public:
    size_t operator()(std::list<int>::iterator const& it) const noexcept {
        return hash<int*>()(&*it);
    }
};
Run Code Online (Sandbox Code Playgroud)

这效果很好。

但是当我尝试概括它并定义以下内容时,

template<typename T>
class std::hash<std::list<T>::iterator> {
public:
    size_t operator()(std::list<T>::iterator const& it) const noexcept {
        return hash<T*>()(&*it);
    }
};
Run Code Online (Sandbox Code Playgroud)

我再次从编译器中看到静态断言失败。为什么这不起作用,定义std::hash任何列表迭代器的正确方法是什么?


编译器详细信息
  • g++(海湾合作委员会)13.2.1 20230801
  • -std=c++23标志(C++23 标准)

c++ template-specialization stdhash c++23

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

如果假设,即 [[assume]] 在常量表达式中失败,会发生什么?

在 C++23 中,该[[assume(conditonal-expression)]]属性使得如果条件表达式的计算结果不为true,则行为未定义。例如:

int div(int x, int y) {
    [[assume(y == 1)]];
    return x / y;
}
Run Code Online (Sandbox Code Playgroud)

y这会编译成与始终相同的代码1

div(int, int):
        mov     eax, edi
        ret
Run Code Online (Sandbox Code Playgroud)

正如评论者所指出的,这不是必需的优化;这正是 GCC 碰巧处理的信息,除了y == 1UB 之外什么都没有。

编译器完全忽略所有假设是有效的。

但是常量表达式呢?

编译器需要诊断常量表达式1)中所有未定义的行为,但这合理吗?例如:

constexpr bool extremely_complicated(int x) {
    bool result;
    // 10,000 lines of math ...
    return result;
}

constexpr int div(int x, int y) {
    // This should result in a compiler error when the compiler …
Run Code Online (Sandbox Code Playgroud)

c++ language-lawyer constant-expression c++23 assumption

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