Diese Form der Template-Template-Parameter wird nur in C++ 17 erlaubt:
template < // v---------- class allowed
template <typename> class TT,
typename T,
std::enable_if_t<std::is_same<TT<T>, Foo<T>>::value, int> = 0
>
Foo<T> create() {
return Foo<T>(T());
}
In C++ 17, beide:
template < // v---------- typename here not allowed
template <typename> typename TT,
typename T,
std::enable_if_t<std::is_same<TT<T>, Foo<T>>::value, int> = 0
>
Foo<T> create() {
return Foo<T>(T());
}
Sie die typename
von class
wies darauf hin, ersetzen müssen kompiliert und sind gleichwertig.
Um Ihre Syntax Foo<int> foo = create<Foo<int>>();
Arbeit zu machen, müssen Sie einfach, dies zu tun:
// default case has no typedef
template<typename>
struct first_param {};
// when a template is sent, define the typedef `type` to be equal to T
template<template<typename> class TT, typename T>
struct first_param<TT<T>> {
using type = T;
};
// template alias to omit `typename` everywhere we want to use the trait.
template<typename T>
using first_param_t = typename first_param<T>::type;
:
template <typename T>
T create() {
return T{};
}
Wenn Sie einschränken möchten, welche Art gesendet werden, können Sie einen Typ Merkmal erstellen müssen
Dann Ihr Merkmal verwenden:
template <
typename T,
void_t<first_param_t<T>>* = nullptr
> // ^---- if the typedef is not defined, it's a subtitution error.
T create() {
return T(first_param_t<T>{});
}
Sie können void_t
wie folgt implementieren:
template<typename...>
using void_t = void;
Live at Coliru
Also, im Wesentlichen, wollen Sie eine 'create' Funktion, die als Vorlage Typ nur ein' Foo 'nimmt und ein' Foo 'zurückgibt? –
NathanOliver
Könnte es nicht einfach sein 'Foo foo = createFoo ();' - als der konstruierte Typ wird immer 'Foo ' sowieso? –
axalis
@axalis ja, ich könnte 'createFoo()' anstelle von 'create >()', aber ich bin auf der Suche nach einer Lösung, die ich für andere Typen, z. 'create >' –
Daskie