(这里的根本问题是,我试图在涉及lambda的复杂表达式上使用decltype
或其他可能基于auto
的其他类型推导。我试图找到某种解决方法。我一直在研究http://pfultz2.github.com/Pythy/用于多态lambdas。如果不告诉大家一个长篇故事,我无法完全进入动机!
我希望能够执行decltype([](int){return 3.5L};
以获取lambda的类型,或者至少返回类型。是的,我知道lambda被赋予了唯一的类型,无需提醒我,如果在两行不同的地方使用decltype([](int){return 3.5L};
,它将给出两种不同的类型。
如果我在lambda上使用decltype
,则会收到一条错误消息(“lambda用于未评估的上下文中”)。我知道这似乎是一条合理的错误消息,但令我感到惊讶的是C++像我一样握着我的手!允许这样做尤其有用,特别是访问lambda的返回类型。这个错误仅仅是由于错误消息过多造成的,还是确实有理由无法完成?
这样的表达式在成员函数中起作用:
template<typename T>
struct X {
void foo() {
static auto l = [](int){return 3.5;};
}
};
但我不允许这样做:
template<typename T>
struct X {
static auto var = [](int){return 3.5;}; // will also fail if I use constexpr here
};
x.cpp:8:47: error: expression ‘#‘lambda_expr’ not supported by
dump_expr#<expression error>’ is not a constant-expression
x.cpp:8:47: error: unable to deduce ‘const auto’ from ‘<expression error>’
这启发了我的想法,尝试在函数中使用静态变量以对lambda进行类型推断。
如果X不是模板,这似乎会更好一些。但是我需要X作为模板-特别是,lambda的参数将采用模板参数的类型。
记住,我只想要lambda的类型,而仅对返回类型感到满意。令人沮丧的是,在这两种情况下,编译器都愿意并且能够进行类型推断和静态初始化,但是这似乎给我带来了一些任意障碍。
我可以从
var_in_func
函数外部访问dummy_func
变量的类型吗?struct S {
constexpr static auto member = a_complicated_expression... // error
void dummy_func() {
static auto var_in_func = a_complicated_expression... // OK
}
typedef dummy_func :: var_in_func the_type; // I'd like this to work
};
如果
a_complicated_expression...
中包含lambda,则member
的初始化程序通常会出现问题。如果S
实际上是一个结构模板,那么我会收到错误消息,说member
没有初始化程序。这就是为什么我试图找到其他解决方法。但是,静态方法
static auto
中的dummy_func
变量可以正常工作。所以这让我想到,它们应该是访问该静态变量类型的好方法?我尝试了以下操作,但由于
dummy_func
不是类型(足够合理),因此无法正常工作:typedef dummy_fun :: var_in_func the_type_of_the_static_variable_in_the_method;
我无法执行
decltype( a_complicated_expression... )
,因为编译器提示在未评估的上下文(declspec)中使用lambda。我正在使用
g++ (Ubuntu/Linaro 4.6.3-1ubuntu5) 4.6.3
。我不介意我是否必须使用g++特定的扩展名。 最佳答案
非捕获的lambda可以转换为函数指针,并具有带有该函数指针签名的operator()
:
template<typename C, typename R, typename... Args>
auto remove_class(R (C::*)(Args...)) -> R(*)(Args...);
template<typename C, typename R, typename... Args>
auto remove_class(R (C::*)(Args...) const) -> R(*)(Args...);
template<typename C, typename R, typename... Args>
auto remove_class(R (C::*)(Args...) volatile) -> R(*)(Args...);
template<typename C, typename R, typename... Args>
auto remove_class(R (C::*)(Args...) const volatile) -> R(*)(Args...);
template<typename T>
auto to_f_ptr(T t) -> decltype(remove_class(&T::operator())) { return t; }
您现在可以编写
auto var = to_f_ptr([](int){return 3.5;});
,并且var
的类型为double (*)(int)
。但是,您仍然无法将lambda用作类范围的
static
初始化程序;参见lambda as a static member。关于c++ - 是否可以访问在另一个函数中定义的自动静态变量的“类型”?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/12251181/