每当调用函数时是否可以生成新类型? 我读过每个lambda都有自己独特的类型,所以我试过了:
template<class T, class F> struct Tag { };
template<class T>
auto func(const T &t) -> auto
{
auto f = [] () {};
return Tag<T, decltype(f)>();
}
static_assert(!std::is_same_v<decltype(func(0)), decltype(func(1))>, "type should be different.");
但是,static_assert失败。
无论类型func()
和T
的值是什么,只要调用func(),t
是否可以返回不同类型的值?
答案 0 :(得分:2)
不,不是在调用函数时。类型是在编译时生成的,而不是在运行时生成的。
查看问题Can the 'type' of a lambda expression be expressed?以下是基于答案的代码。
#include <iostream>
#include <set>
int main()
{
auto n = [](int l, int r) { return l > r; };
auto m = [](int l, int r) { return l > r; };
std::set<int, decltype(n)> s(n);
std::set<int, decltype(m)> ss(m);
std::set<int, decltype(m)> sss(m);
std::cout << (std::is_same<decltype(s), decltype(ss)>::value ? "same" : "different") << '\n';
std::cout << (std::is_same<decltype(ss), decltype(sss)>::value ? "same" : "different") << '\n';
}
结果:
different
same
答案 1 :(得分:0)
C ++是一种静态类型语言,这意味着这些类型只存在于源代码中,并且运行时中几乎没有它们的痕迹。 Lambdas也不例外 - 它们确实具有唯一类型,但它们是在编译时定义的。
模板确实可以用于生成新类型,这是可能的,因为模板在编译时进行评估,因此也只存在于源代码中。
因此严格的答案是否定的,当调用函数时,您无法生成新类型,因为函数调用在运行时发生。
话虽如此,通过一些巧妙的设计,您可以在C ++中实现几乎任何理想的灵活性,只需查看一些常见的设计模式。