【问题标题】:C++ template usage: change variable place leads to compilation errorC++模板使用:改变变量位置导致编译错误
【发布时间】:2017-03-06 07:51:44
【问题描述】:

我有一个像这样的简单程序:

$cat testCompile.cpp

    #include<stdio.h>
    int fd[2];
    template<int fd[]>
    void f(){printf("fd\n");}
    int main(){
        f<fd>();
        return 0;
    }

编译并运行它,没问题,它只是打印“fd”。但是如果我将 fd[2] 的位置更改为 main 函数,则编译失败:

    #include<stdio.h>
    template<int fd[]>
    void f(){printf("fd\n");}
    int main(){
        int fd[2];
        f<fd>();
        return 0;
    }

clang 报告:

    testCompile.cpp:6:5: error: no matching function for call to 'f'
        f<fd>();
        ^~~~~
    testCompile.cpp:3:6: note: candidate template ignored: invalid
          explicitly-specified argument for template parameter 'fd'
    void f(){printf("fd\n");}
         ^
    1 error generated.

此错误表示什么?有什么问题吗?

【问题讨论】:

    标签: c++ linux templates compilation clang


    【解决方案1】:

    首先你需要记住模板是编译时的东西,它全部由编译器处理,在运行时什么都不做。

    那么你需要记住,局部变量最常见的处理方式是把它们放在栈上,而栈的位置可能在编译的时候是不知道的。

    现在如果我们把它们放在一起,因为堆栈分配对象的位置在编译时是未知的,只有在运行时,你不能将堆栈分配(即局部变量)与模板一起使用.

    它适用于全局变量,因为编译器可以知道对象的实际位置。

    【讨论】:

    • 我认为模板是根据对象的数据类型而不是对象的位置来实例化的。如果是这样,那么局部变量和全局变量之间没有区别。
    • 我明白了,它会吐错误,因为它无法找到局部变量在内存中的分配位置,但我不了解全局变量。
    • @PremkumarU 模板可以有非类型参数,以便在编译时传递值。在此示例中,指针作为模板参数传递,因此在函数中fd 不是类型,而是指向int 的指针。就像它作为普通函数参数传递一样。
    • @LorenceHernandez 在大多数现代系统上,堆栈是由操作系统在程序启动时提供的,这就是编译器无法知道位置的原因。但是 global 和 static 变量的位置将具有由编译器和链接器设置的固定位置,这就是编译器将知道它们的位置并将其用于模板参数的原因。
    • @LorenceHernandez 当编译器和链接器创建程序时,它会将程序和可执行文件分成四个部分:数据段(具有全局变量和static 初始化变量)、BSS 段(具有全局和static 未初始化变量),文本段(包含代码,加上字符串文字),最后是堆栈(不存储在可执行文件中)。除了堆栈之外,所有这些段在(虚拟)内存中都有固定的位置(地址)。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-11-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-07-27
    • 2013-04-29
    • 1970-01-01
    相关资源
    最近更新 更多