最近我在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(。我使用的是带有MinGW64 Clang和C++20的Clion。
我知道VS C++编译器添加了一个非标准特性来支持这一点,Clang只使用标准方法。
有人能告诉我解决办法吗?
编辑1:
尝试执行雅科夫·加尔卡的答案中的第一个解决方案。我想这两行[[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);
}
在这种情况下,什么是正确的实施?
错误表明它希望您在命名空间范围内提供专门化。这编译:
class VertexBufferLayout{
std::vector<VertexBufferElement> m_Elements;
public:
VertexBufferLayout(){}
template< typename T >
void Push(GLuint count){}
};
template<>
void VertexBufferLayout::Push<GLfloat>(GLuint count){
m_Elements.push_back({ GL_FLOAT, count, GL_FALSE });
}
//...
或者,您可以使用常规重载来避免专业化:
class VertexBufferLayout{
std::vector<VertexBufferElement> m_Elements;
public:
VertexBufferLayout(){}
template< typename T >
void Push(GLuint count){ Push_(count, (T*)0); }
void Push_(GLuint count, GLfloat*){
m_Elements.push_back({ GL_FLOAT, count, GL_FALSE });
}
//...
};