我有一個template<typename T> class Foo.
我想宣告一個可以回傳任何型別的 Foo 的函式。我會這樣做:template<typename T> Foo<T> bar();
但這意味著我必須像這樣使用它:Foo<SomeConcreteT> f = bar<SomeConcreteT>();,并且SomeConcreteT可能會很長、很笨重而且很煩人,不得不打字。
不過,我確實有一些
using AppleFoo = Foo<ABunchOfStuffForApples>;
using BananaFoo = Foo<SomethingElseForBananas>;
// ...
我更喜歡這樣稱呼 bar: AppleFoo f = bar<AppleFoo>();,所以我不必一直打字ABunchOfStuffForApples,而且從概念上講,AppleFoo它告訴讀者更多關于這里應該發生的事情ABunchOfStuffForApples。
我可以通過添加using TType = T內部Foo和這樣的輔助函式來做到這一點:
template<typename F>
F bar()
{
return bar<F::TType>();
}
但這是丑陋且容易出錯的(例如呼叫bar<SomethingThatIsNotAFoo>())。
有更清潔的方法嗎?
更一般地說,是否有一種測驗某種型別是否為 a 的方法SomethingKnown<SomethingUnknown>,例如在 a 中static_assert?
uj5u.com熱心網友回復:
您可以假裝具有回傳型別推導,方法是擁有bar一個回傳代理的非模板operator Foo<T>
template <typename T>
struct Foo {
/* ... */
};
namespace detail {
struct bar_t {
template <typename T>
operator Foo<T>() { /* current implemenation of bar */ }
};
}
detail::bar_t bar() { return {}; }
using AppleFoo = Foo<struct Apple>;
int main() {
AppleFoo f = bar();
}
uj5u.com熱心網友回復:
您可以創建一個特征以了解它是否為 Foo 并提取其模板引數:
template <typename T>
struct is_foo : std::false_type {};
template <typename T>
struct is_foo<Foo<T>> : std::true_type
{
using type = T;
};
然后
template<typename FOO>
FOO bar()
{
static_assert(is_foo<FOO>::value);
using T = typename is_foo<FOO>::type;
// ...
}
uj5u.com熱心網友回復:
作為替代方案,如果您可以更改呼叫語法,您可能會傳遞一個標簽,一些東西
template <typename T> struct tag {};
然后
template<typename T>
Foo<T> bar(tag<Foo<T>>)
{
return bar<T>();
}
用法類似于
using AppleFoo = Foo<ABunchOfStuffForApples>;
auto bar1 = bar(tag<AppleFoo>{});
auto bar2 = bar(tag<Foo<ABunchOfStuffForApples>>{});
// auto is AppleFoo and so Foo<ABunchOfStuffForApples>
如果您不喜歡介面中的標簽,您仍然可以將其用作實作:
template<typename T>
Foo<T> bar_impl(tag<Foo<T>>)
{
// implementation, such as return Foo<T>();
}
// Possibly other specialization for Foo<std::vector<T>>, Foo<int>, ..
template<typename T>
auto bar()
{
return bar_impl(tag<T>{});
}
有用法
using AppleFoo = Foo<ABunchOfStuffForApples>;
auto bar1 = bar<AppleFoo>();
auto bar2 = bar<Foo<ABunchOfStuffForApples>>();
// auto is AppleFoo and so Foo<ABunchOfStuffForApples>
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/428001.html
上一篇:#include帶有模板的遞回
