c++ - 运行时函数模板类型推导

标签 c++ function templates runtime compile-time

尽管在运行时解析了模板类型,但我试图理解为什么以下编译/运行。是不是因为if/else调用 f仅此一项就足以告诉编译器创建 void f<double>(double)void f<std::string>(std::string)

测试.hpp

#include <type_traits>
#include <string>
#include <iostream>

template <typename T>
void f(T x) {
    if(std::is_same<T, std::string>::value)
        std::cout << "String: " << x;
}

测试.cpp

#include <iostream>
#include "test.hpp"

int main(int, char** argv) {
    double x(std::stod(argv[1]));

    if(x < 42) f(x);
    else f(std::to_string(x));

    return 0;
}

$ (clan)g++ -std=c++14 test.cpp
$ ./a.exe 41

$ ./a.exe 43
String: 43.000000

最佳答案

这里没有进行运行时模板推导。当你有

if(x < 42) f(x);

编译器在编译时知道 x 是一个 double ,所以它会消除

void f<double>(double)

然后在

else f(std::to_string(x));

编译器知道 std::to_string 的返回类型是一个 std::string 所以它去掉了一个

void f<std::string>(std::string)

使用。这两个函数同时存在,并且在运行时只会调用一个函数,具体取决于您为程序提供的输入。

让我们看看this example codechris 提供在他的 comment .使用

#include <type_traits>

template <typename T>
__attribute__((used)) int f(T x) {
    if(std::is_same<T, int>::value)
        return 1;
    else
        return 2;
}

int main(int argc, char** argv) {
    if(argc > 1) return f(1);
    else return f(1.0);
}

使用 -O3 -std=c++1z -Wall -Wextra -pedantic 编译生成程序集

main:                                   # @main
        xor     eax, eax
        cmp     edi, 2
        setl    al
        inc     eax
        ret

int f<int>(int):                        # @int f<int>(int)
        mov     eax, 1
        ret

int f<double>(double):                  # @int f<double>(double)
        mov     eax, 2
        ret

如您所见,两个模板函数都存在于程序集中,只是 main 中的 if 决定在运行时调用哪一个。

关于c++ - 运行时函数模板类型推导,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43656772/

相关文章:

java - 将报告模板 RPT/RDL 转换为 JRXML/Jasper Reports?

c++ - 特定模板特化的重载成员函数

c++ - 如何测量Windows上进程使用的用户时间?

c++ - 使用头文件/源文件来分离接口(interface)和实现

function - 如何使用 OpenCV 和 Python 将鼠标位置保存在变量中?

函数只带出sas中的小数

C++ 结合静态和动态多态性来创建 "Hyper Polymorphism"?

c++ - 在 C++ 中读取带有引号的 CSV/文本文件

c++ - 析构函数中的异常

function - 在 postgresql 中管理修订