c++ - C++中简单可变参数函数的无与伦比的模板?

标签 c++ templates c++14 template-argument-deduction transpiler

我正在为C++编译器编写一个Scheme(尽管Scheme与这个问题不是很相关),并且我有一些在Scheme代码中调用的函数,这些函数可以在生成的C++代码中等效使用。我生成了C++函数“f”(如下所示),我一生都无法弄清为什么它不起作用(错误在下面)。我有三个模板化的参数,并且也为函数提供了三个参数。如果您对此问题有任何见解,请告诉我-这真令人沮丧!

// from stdarg_macros.h
#include <stdarg.h>
#define INIT va_list args; va_start(args, nargs);
#define LOOP for (int i = 0; i < nargs; i++)
#define DEINIT va_end(args); return r;

// from io.cpp
#include <iostream>
template <typename T>
void display(T var) {
        std::cout << var << std::endl;
}

// from operators.c
int add(int nargs, ...) {INIT int r = 0; LOOP r += va_arg(args, int); DEINIT}
double add_d(int nargs, ...) { INIT double r = 0; LOOP r += va_arg(args, double); DEINIT}
int sub(int nargs, ...) {INIT int r; LOOP {if (i == 0) r = va_arg(args, int); else r -= va_arg(args, int);} DEINIT}
double sub_d(int nargs, ...) {INIT int r; LOOP {if (i == 0) r = va_arg(args, double); else r *= va_arg(args, double);} DEINIT}
int mul(int nargs, ...) {INIT int r = 1; LOOP r *= va_arg(args, int); DEINIT}
double mul_d(int nargs, ...) {INIT double r = 1; LOOP r *= va_arg(args, double); DEINIT}
double div_d(int nargs, ...) {INIT double r; LOOP {if (i == 0) r = va_arg(args, double); else r /= va_arg(args, double);} DEINIT}

// my transpiler's output file
template <typename T, typename S, typename M, typename x>
T f(S a, M b, x c) {
return mul_d(3, a, b, div_d(2, 3.0, c));
};

int main() {
        auto m = mul_d(3, 8.0, 2.0, div_d(2, 5.0, 3.0));
        display(m);
        display(f(1, 2, 3));
        return 0;
}
$ g++ -std=c++14 Output/math.cpp && ./a.out
    Output/math.cpp:9:9: error: no matching function for call to 'f'
    display(f(1, 2, 3));
        ^
    Output/math.cpp:3:3: note: candidate template ignored: couldn't infer template argument 'T'
    T f(g a, i b, L c) {
      ^
    1 error generated.

最佳答案

只能从函数参数推导出模板参数。在这种情况下,T的第一个模板参数f不能是deduced,它仅用于指定函数的返回类型。

When possible, the compiler will deduce the missing template arguments from the function arguments.


您必须像这样明确指定参数
display(f<int>(1, 2, 3));
//       ^^^^^
或者,您可以从f中删除模板参数(并推断出返回类型):
template <typename S, typename M, typename x>
auto f(S a, M b, x c) {
    return mul_d(3, a, b, div_d(2, 3.0, c));
};
那你就可以这样称呼它
display(f(1, 2, 3));

关于c++ - C++中简单可变参数函数的无与伦比的模板?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63422467/

相关文章:

javascript - 在 dust.js 中,$idx 的初始值不能从零开始吗?

c++ - 什么时候实例化 constexpr 函数模板?

c++ - 关于循环中值钳位的优化建议

c++ - 为什么 std::get 没有接受转发引用的单一签名

c++ - 如何使用模板参数成员的类型?

c++ - 宏中模板参数数量错误

c++ - 如何在基于范围的for循环中找到当前对象的索引?

c++ - 为什么mac不需要包含智能指针?

c++ - 嵌套模板和参数推导

c++ - istream_iterator 遍历二进制文件中的字节