我写了一个模板,它接受一个istream&和一个函数,应该从 中提取这个函数的所有参数,istream用这些参数调用函数并返回结果。一切正常,除了函数参数的评估顺序。请参阅下面的代码、更多详细信息和最终问题:
#include <iostream>
#include <vector>
void Foo(int i, std::string s)
{
std::cout << "input was " << i << " and " << s << '\n';
}
template<typename T>
T Parse(std::istream &s)
{
T res;
s >> res;
return res;
}
template<typename TR, typename ... TArgs>
TR Bar(std::istream &s, TR f(TArgs...) )
{
return f(Parse<TArgs>(s)...);
}
int main()
{
Bar(std::cin, Foo);
}
Run Code Online (Sandbox Code Playgroud)
输入:
1 2
Run Code Online (Sandbox Code Playgroud)
预期输出:
input was 1 and 2
Run Code Online (Sandbox Code Playgroud)
实际输出:
input was 2 …Run Code Online (Sandbox Code Playgroud) 在实现自定义容器时,我到了需要实现迭代器的地步。当然,我不想为const和non-const迭代器编写两次代码。我发现了这个问题,详细说明了这样的可能实现:
template<class T>
class ContainerIterator {
using pointer = T*;
using reference = T&;
...
};
template<class T>
class Container {
using iterator_type = ContainerIterator<T>;
using const_iterator_type = ContainerIterator<const T>;
}
Run Code Online (Sandbox Code Playgroud)
但是,我也发现了这个这个问题,使用模板参数:
template<class T, bool IsConst>
class ContainerIterator {
using pointer = std::conditional_t<IsConst, const T*, T*>;
using reference = std::conditional_t<IsConst, const T&, T&>;
...
};
template<class T>
class Container {
using iterator_type = ContainerIterator<T, false>;
using const_iterator_type = ContainerIterator<T, true>;
}
Run Code Online (Sandbox Code Playgroud)
第一个解决方案似乎更容易,但是答案是从2010年开始。经过一些研究,似乎第一个版本并未得到广泛使用,但我不知道为什么。我觉得我缺少第一个版本的一些明显缺陷。
因此问题变为:
第一个版本有什么问题吗?
如果没有,为什么版本#2似乎是c ++ …
想象一个非常简单的任务,它需要一个紧密的循环,比如对数组的值求和。我编写了 5 种不同的代码来实现这一点:
const arr = Array(1000000).fill(0).map(() => Math.random());
// 1: (ab)using .forEach
let x1 = 0;
arr.forEach((i) => x1 += i);
// 2. using reduce
let x2 = arr.reduce((a, n) => a + n, 0);
// 3: classic forward for-loop
let x3 = 0;
for(let i = 0; i < arr.length; i++)
x3 += arr[i];
// 4: backward for-loop, should be faster, because comparison with a literal is faster
let x4 = 0;
for(let i = arr.length - 1; …Run Code Online (Sandbox Code Playgroud) 我的问题围绕复制构造和重新分配的机制。
我有一堂课,收集字符串。将字符串添加到集合后,该字符串将被复制并存储在向量中。但是由于我还需要访问所有字符串的集合const char * const*,因此我还通过来存储指向每个字符串数据的指针.c_str()。
class MyStrings {
private:
std::vector<std::string> names;
std::vector<const char*> cStringPointers;
public:
const char *const *Data() const
{
return this->cStringPointers.data();
}
void Add(const std::string &name)
{
// copy [name] and store the copy in [this->names].
this->names.push_back(name);
// Store the pointer to the data of the copy.
this->cStringPointers.push_back(this->names.back().c_str());
}
}
Run Code Online (Sandbox Code Playgroud)
我知道,存储指向向量元素的指针是不好的,因为当向量被调整大小(即必须重新分配其内存)时,这些指针将不再有效。
但是我只存储指向数据的指针。所以这是我的想法:
如果names调整大小,它将移动构造它包含的所有字符串,因此这些字符串将不会分配新的内存,而是仅使用已分配的内存,因此我的指针cStringPointers仍然有效。
我的问题现在很简单:我是否错过了一些会使该代码不安全或导致未定义行为的东西?
(假设我不使用任何奇异的architexture和/或编译器。)
scalar访问 GL_EXT_scalar_block_layout 中的存储缓冲区时,布局说明符有什么用?(例如见下文)
什么是用例scalar?
我最近使用 Vulkan 和 NVidias VkRayTracing 扩展程序编写了一个简单的 Raytracer,并且正在学习本教程。在有关最近命中着色器的部分中,需要访问存储在井存储缓冲区(带有使用标志vk::BufferUsageFlagBits::eStorageBuffer)中的一些数据。
在着色器中,GL_EXT_scalar_block_layout使用了扩展,并像这样访问这些缓冲区:
layout(binding = 4, set = 1, scalar) buffer Vertices { Vertex v[]; } vertices[];
Run Code Online (Sandbox Code Playgroud)
当我第一次使用这段代码时,验证层告诉我结构体Vertex的布局无效,所以我将它们更改为每个成员在 16 字节块上对齐:
struct Vertex {
vec4 position;
vec4 normal;
vec4 texCoord;
};
Run Code Online (Sandbox Code Playgroud)
使用 C++ 中的相应结构:
#pragma pack(push, 1)
struct Vertex {
glm::vec4 position_1unused;
glm::vec4 normal_1unused;
glm::vec4 texCoord_2unused;
};
#pragma pack(pop)
Run Code Online (Sandbox Code Playgroud)
错误消失了,我得到了一个可以工作的 Raytracer。但我仍然不明白为什么scalar这里使用关键字。我发现这个文档在谈论 GL_EXT_scalar_block_layout-extension,但我真的不明白。可能我只是不习惯 glsl 术语?我看不出我必须使用它的任何理由。
此外,我只是试图删除它 …
从 C#12 开始,该语言支持Collection 表达式,它允许使用扩展元素合并集合。
我的问题是,元组是否有一些类似的语法,特别是组合元组?(见下面的例子)
using System;
// Collection expression
int[] arr1 = [1, 2];
int[] arr2 = [3, 4];
int[] arr3 = [..arr1, ..arr2]; // combine using spread element => [1, 2, 3, 4]
// tuples, similar syntax
var tpl1 = (1, 2);
var tpl2 = (3, 4);
// Sadly this doesn't work?
var tpl3 = (..tpl1, ..tpl2); // Cannot implicitly convert type '(int, int)' to 'System.Index'
Run Code Online (Sandbox Code Playgroud)
我知道,我可以这样做:
var tpl3b = (tpl1.Item1, tpl1.Item2, tpl2.Item1, tpl2.Item2); …Run Code Online (Sandbox Code Playgroud) 我使用 winforms 在 C# 中创建了一个非常简单的虚拟应用程序。它仅包含一个 ToolStrip 和该 ToolStrip 内的一个 TrackBar。TrackBar 应具有与 ToolStrip 相同的 BackColor,但 ToolStrip.BackColor 属性似乎不返回实际的背景颜色。
public Form1()
{
//// Here the ToolStrip is created.
//// This code is generated by the designer.
this.InitializeComponent();
//// Here the the TrackBar is created.
//// I think this is impossible to do via the Designer.
this.CreateSpeedSlider();
}
private void CreateSpeedSlider()
{
this.toolStrip.SuspendLayout();
this.speedSlider = new TrackBar
{
TickStyle = TickStyle.None,
AutoSize = false,
Height = this.toolStrip.Height,
Minimum = 0,
Maximum = 10, …Run Code Online (Sandbox Code Playgroud) 我认为这两个程序功能几乎相同,但是python程序运行时间超过70秒,但是c++运行速度非常快。我不明白有什么区别?
测试1.py
import time
x = [(i%10) for i in range(10000)]
y = [(i%10) for i in range(10000)]
start = time.time()
for i in range(10000):
if(i % 100 == 0): print("Current on %d"%i)
for j in range(10000):
r2 = (x[i]-x[j])**2 + (y[i]-y[j])**2
print(time.time()-start)
Run Code Online (Sandbox Code Playgroud)
测试2.cpp
#include <iostream>
#include <time.h>
int main(){
float x[10000];
float y[10000];
time_t start, end;
for(int i=0;i<10000;i++){
x[i] = i%10;
y[i] = i%10;
}
start = time(NULL);
for(int i=0;i<10000;i++){
if(i % 100 == 0) std::cout<<"Current on"<<i<<"\n";
for(int j=0;j<10000;j++){ …Run Code Online (Sandbox Code Playgroud) 我需要在我的 C++ 程序中使用 system() 函数中的 int veriable 。例如:
但我收到错误,我需要有关如何使用此错误的帮助:未找到 C++ 用户定义的文字运算符