小编Dav*_*one的帖子

为什么C++不允许两个具有相同名称的函数/类模板,只有非类型模板参数(整数类型)的类型不同?

我尝试这个时编译器会出错.我试过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)

c++

13
推荐指数
1
解决办法
931
查看次数

在类定义之外定义显式专用类的成员函数

我看到一个与模板有关的错误(编译器是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)

c++

11
推荐指数
1
解决办法
1303
查看次数

为YUV图像使用单个纹理或多个纹理是否更好?

这个问题适用于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的字节数都是相同的,但是纹理越少,开销越少.至少,它会使用更少的纹理单位.我的想法:

  • 如果U和V像素相互散布,我可以将它们加载到GL_LUMINANCE_ALPHA类型的单个纹理中,该纹理有两个组件.
  • 我可以将整个YUV图像加载为单个纹理(类型为GL_LUMINANCE但是图像大小的3/2)然后在片段着色器中我可以在同一纹理上调用texture2D()三次,做一些算术图输出正确的坐标以传递到texture2D以获得Y,U和V组件的正确纹理坐标.

opengl-es opengl-es-2.0

6
推荐指数
1
解决办法
1067
查看次数

glVertexAttribPointer和glEnableVertexAttribArray的范围是什么?

我在Android上使用OpenGL ES 2.0,但我认为这个问题是一般的OpenGL问题.

我正在学习OpenGL,并试图准确理解每帧必须调用哪些API,而不是只调用一次.我最初打电话glVertexAttribPointerglEnableVertexAttribArray每一帧,但当我改变我的测试程序只为每个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)

opengl opengl-es opengl-es-2.0

5
推荐指数
1
解决办法
3669
查看次数

有没有办法分离"内联"关键字的两个含义(ODR放松与功能代码内联)

我想我完全理解inlineC++中关键字的含义.具体来说,它意味着两个只有半相关的东西:

  1. 对于声明的函数,放宽了ODR规则inline.因此,您可以在多个TU中定义相同的功能符号,而不会在链接时出错.这允许在标题中定义函数.
  2. 这是一个建议,它应当与函数的编译代码的副本替换的功能调用,而不是一个编译器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++

5
推荐指数
1
解决办法
132
查看次数

可以在类定义之外定义模板化类的模板化成员方法

我一直在努力确保我理解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)

c++

1
推荐指数
1
解决办法
73
查看次数

在Android上,为什么ps命令在应用程序未分配任何内容时显示高虚拟内存?

我在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分页?

多谢你们!

android

0
推荐指数
1
解决办法
1906
查看次数

标签 统计

c++ ×4

opengl-es ×2

opengl-es-2.0 ×2

android ×1

opengl ×1