c++ - 自动扣除别名模板和模板类的模板参数

标签 c++ templates c++11 c++14 type-deduction

我想使具有可变参数模板参数列表的无状态 lambda 函数成为递归的。但我需要类型删除以避免错误,例如 用“auto”类型声明的变量“lambda”不能出现在它自己的初始值设定项中。 Variadic 模板参数列表要求相应的功能对象具有模板化的operator ()。对于简单的无状态 lambda 函数,我可以将其转换为指向简单的免费旧函数的指针,但是如何为variadic 无状态 lambda 函数实现类似的功能?我想我想要的是模板参数列表的自动类型推导(在模板变量实例化期间:在调用期间或赋值期间):(伪代码)

#include <type_traits>
#include <iostream>

#include <cstdlib>

template< typename first, typename second, typename ...rest >
using fp = first (*)(first const &, second const &, rest const &...); // at least binary function

int
main()
{
    template fp sum = [] (auto const & first, decltype(first) second, auto const &... rest) { return first + sum(second, rest...); };
    //              ^ assignment                                                                                ^ call
    std::cout << sum(1, 2.0, 3.0f) << std::endl;
    return EXIT_SUCCESS;
}

目前是否有可能实现这样的行为 (C++14)(例如,使用 std::function 或其他类型删除方式)?是否有类似语言功能的建议?或者它可能完全被现有的语言规则所禁止?

另一个有用的例子:(伪代码)

template std::vector v{1, 2, 3};
static_assert(std::is_same< decltype(v), std::vector< int > >{});

最佳答案

不,没有办法做你想做的。推导表达式结果的方法是使用 auto .无法推断函数模板或别名模板的类型。考虑最简单的情况:

std::function<auto> if_this_existed = [](int x, int y) { return x + y; };

您可能期望 std::function<int(int, int)> .但是std::function<void(int, int)>作品。 std::function<long(long, long)>也是如此.真的没有一件事可以推断。此外,对于通用 lambda,分配特定类型没有意义:

std::function<void(???)> print = [](auto x) { std::cout << x; };

lambda 可以用任何可打印的类型调用,但无论我们在 ??? 中放入什么会限制 print就是那种类型。所以这也失败了。

所以最终,不,你不能递归地编写你的通用可变参数 lambda。虽然,sum无论如何都不可能递归编写,因为您将无法编写基本案例。写这样一个泛型的正确方法sum()将使用折叠表达式 (C++1z):

auto sum = [] (auto const&... args) {
    return (args + ...);
};

关于c++ - 自动扣除别名模板和模板类的模板参数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33264650/

相关文章:

c++ - std::hash 专门化我自己的类并在类中使用它

c++ - OpenGL 缓冲区对象内部工作原理?

c++ - 使用 C++ 在 Windows 中输入笔

javascript - 如何动态管理不同布局的样式表?

c++ - 调用模板函数的误报错误 503

c++ - C++ vector 上的什么操作会导致赋值运算符调用?

c# - 如果需要,我将如何以编程方式访问或打开交换 edb 文件?

从 C++ JNI NDK 函数调用两次的 Java 方法

c++ - 为什么必须在哪里放置 “template”和 “typename”关键字?

c++ - 读取指向函数中的变量时出现段错误