我尝试这个时编译器会出错.我试过VC++和g ++.
这同样适用于函数模板和类模板(但对于函数模板,只有在实例化函数模板时才会出现编译器错误;当编译器遇到第二个类定义时,会立即出现类模板的编译器错误).
以下是函数模板的示例:
template <unsigned int>
void Foo() {}
template <signed int> // Same name, only difference is the type of the
void Foo() {} // non-type template parameter (of integral type)
Foo<10U>(); // COMPILER ERROR.
Run Code Online (Sandbox Code Playgroud)
上面,为什么编译器不能实例化Foo <unsigned int>()?
如果模板函数/类的第二个版本具有类型模板参数,我发现这不是问题.如果模板函数/类的第二个版本具有非整数类型的非类型模板参数,则也不是问题:
template <unsigned int>
void Foo() {}
template <unsigned int*> // Non-type template parameter
void Foo() {} // of non-integral type
template <typename T> // Type template parameter
void Foo() {}
Foo<10U>(); …Run Code Online (Sandbox Code Playgroud) 我看到一个与模板有关的错误(编译器是Visual Studio 2012),我不明白.这是代码,归结为要点:
// Templated class - generic
template <typename T>
class Test
{
public:
void WorksFine() {} // Comiples and works as expected at runtime
void Problem();
};
// Templated class - expicit specialization for T = int.
template <>
class Test<int>
{
public:
void WorksFine() {} // Comiples and works as expected at runtime
void Problem();
};
// The definition below compiles and works fine at runtime.
template<typename T> void Test<T>::Problem() {}
// The definition below gives error …Run Code Online (Sandbox Code Playgroud) 这个问题适用于OpenGL ES 2.0(在Android上),但可能更适用于OpenGL.
最终,所有性能问题都依赖于实现,但是如果有人能够回答这个问题,或者根据他们的经验来回答这些问题会有所帮助.我也在写一些测试代码.
我有一个YUV(12bpp)图像,我在片段着色器中加载到纹理和颜色转换中.一切正常,但我想看看我可以提高性能(以每秒帧数计).
目前我实际上为每个图像加载了三个纹理 - 一个用于Y组件(类型为GL_LUMINANCE),一个用于U组件(类型为GL_LUMINANCE,当然为1/4大小为Y组件),另一个用于V分量(GL_LUMINANCE类型,当然是Y分量的1/4).
假设我可以在任何排列中获得YUV像素(例如,在单独的平面中或散布的U和V),将三个纹理合并为仅两个还是仅一个?显然,无论你如何操作,推送到GPU的字节数都是相同的,但是纹理越少,开销越少.至少,它会使用更少的纹理单位.我的想法:
我在Android上使用OpenGL ES 2.0,但我认为这个问题是一般的OpenGL问题.
我正在学习OpenGL,并试图准确理解每帧必须调用哪些API,而不是只调用一次.我最初打电话glVertexAttribPointer和glEnableVertexAttribArray每一帧,但当我改变我的测试程序只为每个Shader程序调用一次时,我得到的行为不是我所期望的.
似乎glVertexAttribPointer并且glEnableVertexAttribArray应该只需要调用一次,而不是每个帧,因为它们只在特定的Shader程序的上下文中才有意义.我这样说glVertexAttribPointer是因为它的第一个参数GLuint index是从glGetAttribLocation它返回的,它指定了一个与着色器程序中的变量名对应的字符串.因此,似乎数据与特定着色器程序中的特定"属性"变量相关联.
我的测试程序呈现两个不相交的形状(三角形),使用两个完全不同的程序 - 不同的片段着色器源,不同的顶点着色器源,单独的调用glLinkProgram等.我最初为每个帧运行以下代码,一切都按预期工作 - 我看到两个形状都正确呈现.
m_glhook.glClear(GLES20.GL_COLOR_BUFFER_BIT | GLES20.GL_DEPTH_BUFFER_BIT);
// Shape/Program 1
m_glhook.glUseProgram(m_iGlProgramId);
int iPositionLocation = m_glhook.glGetAttribLocation(m_iGlProgramId, "a_Position");
m_bfVertices.rewind();
m_glhook.glVertexAttribPointer(iPositionLocation, 4, GLES20.GL_FLOAT, false, STRIDE, m_bfVertices);
m_glhook.glEnableVertexAttribArray(iPositionLocation);
gl.glDrawArrays(GLES20.GL_TRIANGLES, 0, 3);
// Shape/Program 2
m_glhook.glUseProgram(m_iGlProgramId2);
int iPositionLocation2 = m_glhook.glGetAttribLocation(m_iGlProgramId2, "a_Position");
m_bfVertices2.rewind();
m_glhook.glVertexAttribPointer(iPositionLocation2, 4, GLES20.GL_FLOAT, false, STRIDE, m_bfVertices2);
m_glhook.glEnableVertexAttribArray(iPositionLocation2);
gl.glDrawArrays(GLES20.GL_TRIANGLES, 0, 3);
Run Code Online (Sandbox Code Playgroud)
然后我修改了为每个帧进行的调用,如下所示. m_bFirstDraw第一帧为true,连续帧为false.
m_glhook.glClear(GLES20.GL_COLOR_BUFFER_BIT | GLES20.GL_DEPTH_BUFFER_BIT);
// Shape/Program 1
m_glhook.glUseProgram(m_iGlProgramId); …Run Code Online (Sandbox Code Playgroud) 我想我完全理解inlineC++中关键字的含义.具体来说,它意味着两个只有半相关的东西:
inline.因此,您可以在多个TU中定义相同的功能符号,而不会在链接时出错.这允许在标题中定义函数.call指令功能符号的地址.我可以理解这两个含义必然在一个方向上相关:2必须暗示1.#2要求函数定义可用于调用该函数的所有TU.因此,函数定义必须存在于多个TU中.因此,需要放宽ODR以避免链接器错误.
但我的问题是关于另一个方向 - 为什么语言设计为1必须暗示2?
在某些情况下和某些设计决策中,希望能够放松函数的ODR似乎是合理的,而不向编译器建议它应该实际内联函数代码.如果我有一个函数,我想通过头文件分发,我必须将其标记为inline放松ODR(#1).但是现在我被迫进入#2,即使我有特定的知识,在性能方面,该功能不适合内联.
我的理解是模板功能不存在这种不必要的含义.ODR会自动放宽模板功能(必须如此).这允许我inline仅用作性能建议.
我知道在头文件中分发函数,而不是像静态库,可能是一个坏主意.但作为一名程序员,我有可能知道自己在做什么,我希望这种灵活性.我有模板功能的灵活性,为什么不模板功能呢?
或者是否有一种可移植的方式来放松ODR而不建议内联函数?例如,在MSVC上你可以这样做:
__declspec(noinline) inline void Foo() {}
Run Code Online (Sandbox Code Playgroud)
这里inline放宽了ODR,但__declspec(noinline)要求编译器实际上没有内联调用.但是__declspec(noinline)不便携.
谢谢!
我一直在努力确保我理解C++模板的语法,而且我认为我归结为最后一个案例.如果我有一个模板化的类,它具有模板化的方法(与类的模板参数无关),我可以在类定义之外定义该方法吗?如果是这样,语法是什么?
如果模板化方法是在模板化类定义中定义的,那么一切都很好.但是为了在类外定义方法,我尝试了很多关键字和尖括号的组合,我总是遇到编译器错误(Visual Studio 2012).
这是问题,归结为:
template <typename T>
class TestClass
{
public:
// ctor
TestClass(T classtype) {m_classtype = classtype;}
// The declaration/definition below is fine.
template <typename U> void MethodOk(U param) {printf("Classtype size: %d. Method parameter size: %d\n", sizeof(m_classtype), sizeof(param));}
// The declaration below is fine, but how do I define the method?
template <typename U> void MethodProblem(U param); // What is the syntax for defining this outside the class definition?
private:
T m_classtype;
};
Run Code Online (Sandbox Code Playgroud) 我在Android上使用ps命令来确定应用程序使用的内存(只是一个普通的基于Java的应用程序).我有一个测试应用程序,它分配尽可能多的内存(通过重复创建1兆字节的数组,并将它们添加到List中,这样它们就不会超出引用,直到分配失败).
ps为测试应用程序显示的"RSS"(Resident Set Size)列似乎是明智的 - 当应用程序启动时它很低,然后在我分配了一堆内存后它会高得多.但VSIZE/VSS列开始时非常高,并且不会更改.在Android上由ps报告的VSIZE/VSS列的含义是什么?
在明确分配任何内存之前,这是我的测试应用程序的ps输出.单位是千字节
USER PID PPID VSIZE RSS WCHAN PC NAME
u0_a55 2271 91 468664 30008 ffffffff 00000000 S com.dave.quicktest
Run Code Online (Sandbox Code Playgroud)
这是在我分配内存直到筋疲力尽之后:
USER PID PPID VSIZE RSS WCHAN PC NAME
u0_a55 2271 91 468692 287232 ffffffff 00000000 S com.dave.quicktest
Run Code Online (Sandbox Code Playgroud)
从30mb到287mb时的RSS,差异大致与分配的内存量相匹配.但VSIZE一开始就是468mb,而且变化不大.为什么?
另外,我可以确认Android OS实际上没有使用页面文件/交换空间吗?我不怀疑有可能构建/配置它这样做,但在正常的库存操作系统构建中,它是否会对存储进行VM分页?
多谢你们!