我正在阅读一篇关于if consteval (\xc2\xa73.2)的 C++ 论文,并看到一段显示constexpr strlen实现的代码:
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}\nRun Code Online (Sandbox Code Playgroud)\n我是来询问__asm__else分支中的语句的。
我知道这是幽默,并不意味着要认真对待,但我仍然决定做一些研究,以防有人已经解释过。\n当我用谷歌搜索引用的消息时,我得到的结果不到 10 个,全部都是关于这段代码的.\n然后我研究了什么是SSE 4.2,发现它是一个CPU指令集,所以我真的不知道它在C++论文中出现的内容,有人有解释吗?\n感谢那些会阅读的人我的帖子。
\nauto (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>完美转发使用通用/转发引用声明的输入参数?
我想使用概念来区分一维和二维容器。我的第一次尝试如下:
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++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, …
在以下代码中,它在 -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++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)
这在编译阶段是不是更难捕捉?
谢谢。
因此,在我正在处理的项目中尝试对函数指针使用显式对象参数时,我遇到了问题。乍一看,代码在语法上似乎很好,但由于这是一个新功能,我在网上找不到太多信息,所以我不知道为什么会出现随机语法错误。具体来说,错误是“语法错误:')'”
我唯一真正的猜测是,这是某种 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 中部分实现。
我正在尝试将一个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) 假设我们有一段代码如下
#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任何列表迭代器的正确方法是什么?
-std=c++23标志(C++23 标准)在 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++ ×10
c++23 ×10
assumption ×1
auto ×1
c++-chrono ×1
c++-concepts ×1
concept ×1
containers ×1
fstream ×1
reference ×1
sse ×1
sse4 ×1
std-ranges ×1
stdhash ×1
type-traits ×1
visual-c++ ×1