例:
template <typename T>
class Bar
{
public:
void foo(T&& arg)
{
std::forward<T>(arg);
}
};
Bar<int> bar;
bar.foo(10); // works
int a{ 10 };
bar.foo(a); // error C2664: cannot convert argument 1 from 'int' to 'int &&'
Run Code Online (Sandbox Code Playgroud)
通用引用似乎只适用于模板化函数,只适用于类型推导,对吧?所以在课堂上使用它没有意义吗?std::forward在我的案例中使用是否有意义?
我需要从函数返回一个const引用.这段代码完成了这件事:
auto test()->add_lvalue_reference<const int>::type
{
static int i{50};
return i;
}
int & i{test()}; // doesn't compile
Run Code Online (Sandbox Code Playgroud)
但是这个看起来非常相似的片段给出了错误的结果:
auto const test()->add_lvalue_reference<int>::type
{
static int i{50};
return i;
}
int & i{test()}; // compiles thougth test() returned a const
Run Code Online (Sandbox Code Playgroud)
我将关键字const从类型声明移动到返回声明.
起初,我想,在扣除后,函数签名变成了第二种情况:
int & const test(); // not valid - const qualifiers cannot be applied to int&
Run Code Online (Sandbox Code Playgroud)
这不是一个有效的c ++.但是使用auto说明符编译它.
所以我的问题是const函数返回类型具有自动跟踪返回的含义是什么?或者也许它被丢弃了?
我过去曾经有过使用DirectX12的经验,我不记得类似于Vulkan渲染过程的东西,所以我无法进行类比.如果我正确理解同一个子通道内的命令缓冲区不需要同步.那么为什么要复杂化并使它们成倍增加呢?为什么我不能只使用一个命令缓冲区并将所有与帧相关的信息放在那里?
我有一个统一的缓冲区,应该每帧更新.为了避免大的停顿,我想创建3个缓冲区(按我的帧缓冲区的数量),每个帧应该交错(0-1-2-0-1-2 -...).但我无法理解如何创建描述符并绑定它们.这就是我现在这样做的方式:
VkDescriptorSetLayout我指定的位置,我想在某个着色器阶段中在绑定位置0使用统一缓冲区.VkDescriptorPool一个大小为3个描述符的统一缓冲区.VkDescriptorSetLayout,我期待得到一个VkDescriptorSet.VkDescriptorBufferInfo其中将传递给VkWriteDescriptorSet它vkUpdateDescriptorSets.但是其他两个缓冲区呢?在哪里指定它们?我需要VkDescriptorSetLayout为每一帧创建3 - 1吗?接下来我需要使用相应的缓冲区分配和更新相应的描述符集吗?在此之后,我需要创建3个不同的命令缓冲区,我应该指定相应的描述符集.
这似乎是很多工作 - 数据几乎相同 - 所有绑定,状态保持不变,只有缓冲区发生变化.
所有这一切听起来都很混乱,所以请不要犹豫澄清.
我试图理解为什么我们需要VkAttachmentReference::layout?文档说:
layout是VkImageLayout指定附件在子通道期间使用的布局的值。
换句话说,它告诉在子通道开始之前附件将转换到哪个布局。
但是这些信息已经可以通过VkAttachmentDescription::initialLayout. 这是文档中的引用:
initialLayout是渲染过程实例开始时附件图像子资源将处于的布局。
是不是VkAttachmentReference::layout冗余,因为它完全重复VkAttachmentDescription::initialLayout?
我有一大块设备内存和多个想要绑定的统一缓冲区。显然,我需要一个补偿。让我们看看文档是怎么vkBindBufferMemory说的:
memoryOffset是要绑定到缓冲区的内存区域的起始偏移量...
memoryOffset必须是调用 with buffer返回的结构alignment成员的整数倍VkMemoryRequirementsvkGetBufferMemoryRequirements
好的,很清楚 - 我有多个使用相同标志创建的统一缓冲区,因此我可以对所有缓冲区使用相同的对齐方式。但是等等,规格中还有另一个使用说明vkBindBufferMemory:
如果缓冲区是用创建的
VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT,memoryOffset则必须是VkPhysicalDeviceLimits::minUniformBufferOffsetAlignment
这很令人困惑。我可以安全地用于VkPhysicalDeviceLimits::minUniformBufferOffsetAlignment我的情况,还是应该将其进行比较VkMemoryRequirements::alignment并选择最低的?
所以我有一个渲染通道,它带有一个直接绘制到帧缓冲区的子通道。规范并没有强迫我使用依赖项——如果我省略它们,实现会隐式插入它们(虽然我不明白为什么它srcStageMask = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT用于第一个子通道——这个阶段意味着最开始,即不要等待任何东西)。
但与 Vulkan 一样 - 最好是明确的。这是混淆 - 多个来源以不同的方式使用子通道。
Sdk 的立方体示例根本不使用它们。
Vulkan-tutorial 只使用一个:
dependency.srcSubpass = VK_SUBPASS_EXTERNAL;
dependency.dstSubpass = 0;
dependency.srcStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
dependency.srcAccessMask = 0;
dependency.dstStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
dependency.dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
Run Code Online (Sandbox Code Playgroud)
为什么srcAccessMask这里是零?
没有秘密的 API 使用两个:
dependency.srcSubpass = VK_SUBPASS_EXTERNAL;
dependency.dstSubpass = 0;
dependency.srcStageMask = VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT;
dependency.srcAccessMask = VK_ACCESS_MEMORY_READ_BIT;
dependency.dstStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
dependency.dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
Run Code Online (Sandbox Code Playgroud)
和
dependency.srcSubpass = 0;
dependency.dstSubpass = VK_SUBPASS_EXTERNAL;
dependency.srcStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
dependency.srcAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
dependency.dstStageMask = VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT;
dependency.dstAccessMask = VK_ACCESS_MEMORY_READ_BIT;
Run Code Online (Sandbox Code Playgroud)
这不是很清楚,为什么 …
但无论如何,我无法比较成员函数。这是一个例子:
class ClassA
{
public:
int add(int a, int b)
{
return a + b;
}
};
int main()
{
ClassA a1{};
function<int(int, int)> f1 = bind(&ClassA::add, a1, placeholders::_1, placeholders::_2);
function<int(int, int)> f2 = bind(&ClassA::add, a1, placeholders::_1, placeholders::_2);
cout << boolalpha << "f1 == f2 " << (f1.target_type() == f2.target_type()) << endl; // true
cout << (f1.target<int(ClassA::*)(int, int)>() == nullptr) << endl; // true
return 0;
}
Run Code Online (Sandbox Code Playgroud)
从代码中可以明显看出f1和f2是不同的。第一个cout显示true …
我知道这个问题被问了一百万次.大多数答案只是说对象应该是CopyAssignable和CopyConstructible.但文档清楚地说这是规则(直到C++ 11)!但它仍然无效.为什么?
我有这个代码:
template<typename ...T>
struct Test
{
void call(string str)
{
abc(get<T>(str)...);
}
template<typename U>
string get(string& inp)
{
string ret{ inp[0] };
inp.erase(0, 1);
cout << ret << endl; // first "a", next "b", next "c" - everything is ok
return ret;
}
void abc(string a, string b, string c)
{
cout << a << " " << b << " " << c << endl; // "b c a" - why?
}
};
Run Code Online (Sandbox Code Playgroud)
我这样称呼它:
Test<int, bool, float> test;
test.call("abc"); …Run Code Online (Sandbox Code Playgroud)