找到了看起来很有趣的这段代码:
auto a = [](){};
class B : decltype(a)
{
};
我想知道它的作用。这有什么用吗?
最佳答案
好的,该代码可以编译,但是问题是您将无法默认构造该class1的任何对象,因为无法访问lambda的构造函数(复制/移动构造函数除外)。 lambda
类型保证的唯一构造函数是默认的复制/移动构造函数。而且没有默认的构造函数
[expr.prim.lambda/21]
或来自cppreference:
//ClosureType() = delete; //(until C++14)
ClosureType(const ClosureType& ) = default; //(since C++14)
ClosureType(ClosureType&& ) = default; //(since C++14)
Lambda构造函数不可访问的历史可以追溯到其早期提议,发现here
在第三部分第二段中,我引用:
如您所见,该建议甚至建议禁止从闭包类型创建派生类。
1当然,您可以使用
a
复制初始化基类以初始化B
类型的对象。参见this现在,您的问题是:
并非以您的确切形式。您的实例只能使用实例
a
实例化。但是,如果您从诸如lambda类型之类的通用Callable类继承,则可以想到两种情况。
一个简化的例子:
template<typename TFirst, typename... TRemaining>
class FunctionSequence : public TFirst, FunctionSequence<TRemaining...>
{
public:
FunctionSequence(TFirst first, TRemaining... remaining)
: TFirst(first), FunctionSequence<TRemaining...>(remaining...)
{}
template<typename... Args>
decltype(auto) operator () (Args&&... args){
return FunctionSequence<TRemaining...>::operator()
( TFirst::operator()(std::forward<Arg>(args)...) );
}
};
template<typename T>
class FunctionSequence<T> : public T
{
public:
FunctionSequence(T t) : T(t) {}
using T::operator();
};
template<typename... T>
auto make_functionSequence(T... t){
return FunctionSequence<T...>(t...);
}
用法示例:
int main(){
//note: these lambda functions are bug ridden. Its just for simplicity here.
//For correct version, see the one on coliru, read on.
auto trimLeft = [](std::string& str) -> std::string& { str.erase(0, str.find_first_not_of(' ')); return str; };
auto trimRight = [](std::string& str) -> std::string& { str.erase(str.find_last_not_of(' ')+1); return str; };
auto capitalize = [](std::string& str) -> std::string& { for(auto& x : str) x = std::toupper(x); return str; };
auto trimAndCapitalize = make_functionSequence(trimLeft, trimRight, capitalize);
std::string str = " what a Hullabaloo ";
std::cout << "Before TrimAndCapitalize: str = \"" << str << "\"\n";
trimAndCapitalize(str);
std::cout << "After TrimAndCapitalize: str = \"" << str << "\"\n";
return 0;
}
输出
Before TrimAndCapitalize: str = " what a Hullabaloo "
After TrimAndCapitalize: str = "WHAT A HULLABALOO"
看到它Live on Coliru
operator()(...)
的Functor,重载所有基类的operator()(...)
:另一个很酷的技巧:由于
make_functionSequence(...)
产生的类型是可调用的类。您可以在以后附加更多lambda或可调用的lambda。 //.... As previously seen
auto trimAndCapitalize = make_functionSequence(trimLeft, trimRight, capitalize);
auto replace = [](std::string& str) -> std::string& { str.replace(0, 4, "Whaaaaat"); return str; };
//Add more Functors/lambdas to the original trimAndCapitalize
auto replaced = make_functionSequence(trimAndCapitalize, replace /*, ... */);
replaced(str2);
关于c++ - 从lambda继承意味着什么?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/38024024/