[英]C++17 Inheriting set of lambdas with template argument deduction guides
[英]Templated lambdas in C++17 without an auto argument
我有一個繼承自Base<ResourceType>
類的Derived
類:
template <class ResourceType>
class Base {
protected:
ResourceType* resource;
public:
void set_resource(ResourceType* resource) {
this->resource = resource;
}
};
template <class ResourceType>
class Derived : public Base<ResourceType> {
public:
using Base<ResourceType>::resource;
void print () {
std::cout << *resource << std::endl;
}
};
我想創建一個創建Derived
類型對象的工廠。 我當然可以用功能做到這一點:
template <typename ResourceType>
auto derived_factory () {
return new Derived<ResourceType>();
}
auto derived = *(derived_factory<int>());
但是,我無法為工廠編寫lambda函數。 如果我使用auto關鍵字接受模板參數,我可以編寫模板化的lambda函數,但在這里我只想使用模板來確定返回類型。 以下失敗:
auto derived_factory = []<typename ResourceType>() {
return new Derived<ResourceType>();
};
auto derived = *(derived_factory<int>());
有錯誤:
inherit_unknown_type.cpp: In function ‘int main()’:
inherit_unknown_type.cpp:27:36: error: expected primary-expression before ‘int’
auto derived = *(derived_factory<int>());
^~~
inherit_unknown_type.cpp:27:36: error: expected ‘)’ before ‘int’
我只是錯誤地調用了lambda嗎? 或者我必須等待C++20
?
lambda表達式中的模板參數列表是C ++ 20的一個特性 。
(事實上,我的GCC在診斷中說: error: lambda templates are only available with -std=c++2a or -std=gnu++2a [-Wpedantic]
)
但是你不必等待C ++ 20,它已經被GCC 8 支持 -std=c++2a
標志。
而且你必須改變調用語法:而不是derived_factory<int>()
,你需要derived_factory.operator()<int>()
。
作為替代方案(如果您不想要免費功能),我建議使用標簽調度的變體:
auto derived_factory = [](auto tag) {
return new Derived<typename tag::type>();
};
template <typename T> struct tag_type {using type = T;};
// Usage:
derived_factory(tag_type<int>{})
此外,即使你以某種方式編譯它,這一行:
auto derived = *(derived_factory<int>());
無論如何都會導致內存泄漏。 為避免這種情況,您應將結果存儲為指針或引用。 或者甚至更好,使用智能指針。
等待C ++ 20,您可以從模板類返回lambda
template <typename ResourceType>
auto make_derived_factory ()
{ return []{ return new Derived<ResourceType>{}; }; }
auto derived = make_derived_factory<int>();
int main ()
{
auto df { derived() };
}
以上不起作用,但這樣做:
auto derived_factory = [](auto tag)
{
return new Derived<decltype(tag)::type>();
};
template <typename T> struct tag_type {using type = T;};
// Usage:
derived_factory(tag_type<int>{})
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.