【发布时间】:2021-03-25 00:01:30
【问题描述】:
最近我在 YouTube 上学习 OpenGL 基础知识,当我使用 VS C++ 编译器时,一切都像一个魅力,但自从我搬到 Clang 后,我从下面的代码中收到错误“非命名空间范围内的显式专业化”:
class VertexBufferLayout{
private:
std::vector<VertexBufferElement> m_Elements;
public:
VertexBufferLayout(){}
template< typename T >
void Push(GLuint count){}
template<>
void Push<GLfloat>(GLuint count){
m_Elements.push_back({ GL_FLOAT, count, GL_FALSE });
//Rest of code
}
};
*这是一段不完整的类定义,但我想让这段代码更清晰。
基本上,我想要的只是创建几个函数,每个类型都有一个(我是模板的新手 :D)。 我将 Clion 与 MinGW64 Clang 和 C++20 一起使用。
我知道 VS C++ 编译器添加了一个非标准特性来支持这一点, 而 Clang 只使用标准方法。
谁能告诉我解决方法?
编辑 1:
尝试从 Yakov Galka 的回答中实施第一个解决方案。 我猜这两个 [[nodiscard]] 行或 m_Stride 变量可能会搞砸。我收到错误“多重定义”。
(这次是完整的代码)我应该从一开始就这样发布。
class VertexBufferLayout{
std::vector<VertexBufferElement> m_Elements;
GLuint m_Stride;
public:
VertexBufferLayout(): m_Stride(0) {}
[[nodiscard]] std::vector<VertexBufferElement> GetElements() const& { return m_Elements; };
[[nodiscard]] inline GLuint GetStride() const { return m_Stride; }
template< typename T >
void Push(GLuint count){}
};
template<>
void VertexBufferLayout::Push<GLfloat>(GLuint count){
m_Elements.push_back({ GL_FLOAT, count, GL_FALSE });
m_Stride += count * VertexBufferElement::GetSizeOfType(GL_FLOAT);
}
在这种情况下,正确的实现是什么?
【问题讨论】:
-
你必须在你
#included多次的标题中写过它。以template<> inline void ...开始您的专业化,以允许多个定义并确保您的标头使用包含保护或#pragma once。 -
我已经在使用
#pragma once但这个inline关键字让一切正常。最后一个问题,就性能和代码清晰度而言 - 重载(您的第二个解决方案)是否更优化? -
在性能方面它们将是相同的。在代码清晰度方面——我认为你最好不要写那个类。看起来有很多代码,最终只有几个
glVertexAttribPointer调用。 -
非常感谢您的回复!我会考虑的。
标签: c++ opengl clang explicit-specialization