[英]Using recursive variadic template parameters in function return type
我正在嘗試編寫一個可變參數模板 function,它可以嘗試對它的參數進行any_cast
並在第一次成功轉換時返回一個variant
,我已經使用折疊表達式成功地完成了這個但是為了好玩我嘗試將它寫成一個遞歸模板我遇到了以下錯誤。 這是由於每個遞歸實例的返回類型都會更改這一事實引起的。
error: no viable conversion from returned value of type 'variant<float, std::basic_string<char>, (no argument)>' to function return type 'variant<int, float, std::basic_string<char>>'
這是我的 function
template <typename T, typename... Ts>
std::variant<T, Ts...> try_any_cast(std::any const & a)
{
if constexpr (sizeof...(Ts) > 0)
{
if (auto result = std::any_cast<T>(&a))
{
return std::any_cast<T>(a);
}
return try_any_cast<Ts...>(a);
}
else
{
throw std::bad_any_cast();
}
}
預計會像這樣使用
std::any a = 5;
auto value = try_any_cast<int, float, std::string>(a);
我如何為所有實例化存儲和使用原始模板參數包,以便唯一和最終的返回類型是std::variant<int, float, std::string>
?
您可以通過存儲原始參數包來存儲原始參數包。 好吧,聽起來很奇怪,但那是因為你基本上描述了解決方案應該是什么樣子而沒有真正找到解決方案。 有一個輔助模板會很有幫助。 糟糕,我 go 又重復了一遍。 是時候了解一些細節了。
助手可以接受一個附加參數,即返回類型。 否則它看起來很像您當前的模板。
// Add parameter `R` for the return type
template <typename R, typename T, typename... Ts>
R try_any_cast_return(std::any const & a)
{
if constexpr (sizeof...(Ts) > 0)
{
if (auto result = std::any_cast<T>(&a))
{
return std::any_cast<T>(a);
}
return try_any_cast_return<R, Ts...>(a);
}
else
{
throw std::bad_any_cast();
}
}
一旦你有了它,你希望人們使用的模板只是一個插入所需返回類型的包裝器。
template <typename... Ts>
std::variant<Ts...> try_any_cast(std::any const & a)
{
return try_any_cast_return<std::variant<Ts...>, Ts...>(a);
}
你是 go。原始參數包存儲在提供給助手模板的新參數中,不會影響原始模板的使用方式。
如果有人也對我最初如何使用折疊表達式解決此問題感興趣
template <typename... Ts>
auto try_any_cast(std::any any)
{
std::variant<Ts...> result;
if (not ((any.type() == typeid(Ts)
? (result = std::variant<Ts...>(std::any_cast<Ts>(any)), true)
: false)
|| ...))
throw std::bad_any_cast();
return result;
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.