Две базы кода с одинаковым кодом, но одна генерирует ошибку компиляции с разрешением перегрузки, а другая нет - PullRequest
1 голос
/ 20 сентября 2019

Я слежу за исходным кодом Джонно Робсона для приложения Vulkan, которое можно найти на github здесь: Vulkan-Terrain-Generator .Я использую Visual Studio 2017 на 7-битной машине Windows.

У меня есть собственное решение и проект, в котором все было напечатано вручную, но у меня также есть загруженный клон для их проекта, чтобы я мог использовать его бок о бок, пытаясь изучить и лучше понять ВулканAPI.

В функции initPipelines() класса Renderer мы настраиваем все различные конвейеры для визуализированной сцены.В разделе, где мы настраиваем TerrainRenderingPipeline , есть вызов addTextureArray(), который унаследованный класс вызывает из своего члена базового класса.Класс TerrainRenderingPipeline наследуется от базового класса Pipeline .

Вот как он вызывается в методе initPipelines() класса Render :

terrain_rendering_pipeline_->addTextureArray(VK_SHADER_STAGE_VERTEX_BIT, 3, terrain_generator_->getHeightmaps());

В моем решении;это не в состоянии компилироваться, и Visual Studio генерирует ошибку C2664 с жалобой на разрешение перегрузки.Тем не мение;когда я компилирую и собираю проект Джонно, проблем не возникает.


Это объявления функций для addTextureArray(...) функций, которые можно найти в pipeline.h:

void addTextureArray(VkShaderStageFlags stage_flags, uint32_t binding_location, std::vector<Texture*>& textures);
void addTextureArray(VkShaderStageFlags stage_flags, uint32_t binding_location, std::vector<VkImageView>& textures);

иэто определения, которые можно найти в pipeline.cpp

void VulkanPipeline::addTextureArray(VkShaderStageFlags stage_flags, uint32_t binding_location, std::vector<Texture*>& textures) {
    Descriptor texture_descriptor = {};

    // setup image info
    for (Texture* texture : textures) {
        VkDescriptorImageInfo image_info = {};
        image_info.imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
        image_info.imageView = texture->getImageView();
        image_info.sampler = VK_NULL_HANDLE;
        texture_descriptor.image_infos.push_back(image_info);
    }

    // setup descriptor layout info
    texture_descriptor.layout_binding.descriptorType = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE;
    texture_descriptor.layout_binding.descriptorCount = texture_descriptor.image_infos.size();
    texture_descriptor.layout_binding.binding = binding_location;
    texture_descriptor.layout_binding.stageFlags = stage_flags;
    texture_descriptor.layout_binding.pImmutableSamplers = nullptr;

    descriptor_infos_.push_back(texture_descriptor);
}

void VulkanPipeline::addTextureArray(VkShaderStageFlags stage_flags, uint32_t binding_location, std::vector<VkImageView>& textures) {
    Descriptor texture_descriptor = {};

    // setup image info
    for (VkImageView texture : textures) {
        VkDescriptorImageInfo image_info = {};
        image_info.imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
        image_info.imageView = texture;
        image_info.sampler = VK_NULL_HANDLE;
        texture_descriptor.image_infos.push_back(image_info);
    }

    // setup descriptor layout info
    texture_descriptor.layout_binding.descriptorType = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE;
    texture_descriptor.layout_binding.descriptorCount = texture_descriptor.image_infos.size();
    texture_descriptor.layout_binding.binding = binding_location;
    texture_descriptor.layout_binding.stageFlags = stage_flags;
    texture_descriptor.layout_binding.pImmutableSamplers = nullptr;

    descriptor_infos_.push_back(texture_descriptor);
}

Наконец, для TerrainGenerator функция класса getHeightmaps() класса, которая возвращает std::vector<VkImageView>, находится в terrain_generator.h:

inline std::vector<VkImageView> getHeightmaps() { return heightmap_image_views_; }

Я полагаю, что это весь соответствующий код, который затрагивает эту проблему.


Вот сгенерированная ошибка компилятора Visual Studio:

1>c:\users\skilz99\source\repos\vulkan terrain generator\vulkan terrain generator\renderer.cpp(522): error C2664: 'void VulkanPipeline::addTextureArray(VkShaderStageFlags,uint32_t,std::vector<VkImageView,std::allocator<_Ty>> &)': cannot convert argument 3 from 'std::vector<VkImageView,std::allocator<_Ty>>' to 'std::vector<Texture *,std::allocator<_Ty>> &'
1>        with
1>        [
1>            _Ty=VkImageView
1>        ]
1>        and
1>        [
1>            _Ty=VkImageView
1>        ]
1>        and
1>        [
1>            _Ty=Texture *
1>        ]
1>c:\users\skilz99\source\repos\vulkan terrain generator\vulkan terrain generator\renderer.cpp(545): warning C4305: 'argument': truncation from 'double' to 'T'
1>        with
1>        [
1>            T=float
1>        ]

Что я не понимаю, так это почему не удается скомпилировать в моем проекте-решении, ноне в его ... Любые советы или предложения будут очень полезны.Если вам нужна дополнительная информация о коде, пожалуйста, не стесняйтесь спрашивать.Я попытался опубликовать минимально возможный объем кода, так как это проект приличного размера.

Ответы [ 2 ]

2 голосов
/ 20 сентября 2019

Когда вы используете функцию getHeightmaps в вызове addTextureArray, возвращаемый объект является временным объектом.Временные объекты не могут быть связаны с неконстантными ссылками.И addTextureArray принимает аргумент неконстантной ссылки для вектора.

Либо необходимо изменить addTextureArray функцию, чтобы принять ссылку const в качестве третьего аргумента:

void addTextureArray(VkShaderStageFlags, uint32_t, std::vector<Texture*> const&);
void addTextureArray(VkShaderStageFlags, uint32_t, std::vector<VkImageView> const&);

Или Вы должны изменить функцию getHeightmaps, чтобы получить ссылку:

inline std::vector<VkImageView>& getHeightmaps() { return heightmap_image_views_; }
0 голосов
/ 20 сентября 2019

После учета ответа Some programmer dude, который будет правильным способом решения такой проблемы в соответствии с современными рекомендациями C ++.Это все еще заставляло меня задуматься, почему код будет компилироваться по решению Джонно, а не по моему.Тогда Some programmer dude упомянул в комментарии:

Различные флаги сборки?Или что-то еще, что отличается от вашей сборки.Это невозможно сказать по-настоящему.

Поэтому я вернулся и проверил настройки проекта, и, к моему удивлению, был один флаг компилятора, который я просмотрел, который был другим.

Вмое решение по умолчанию при его первоначальном создании в:

  • Свойства конфигурации
    • C / C ++
      • Язык -> Режим соответствия

Моя была по умолчанию установлена ​​на Yes (/permissive-), а в проекте Jonno его было установлено на №.

Как только я изменил это в свойствах моего проекта, он теперь компилируется.

...