Was ist die korrekte Signatur?
Soweit ich weiß, ist es nicht möglich, eine einzige korrekte Signatur zu schreiben, um alle Container und nur Container abzufangen.
aber wenn man eine Art Züge schreiben akzeptieren, die sagen, wenn ein Typ ist ein Container und extrahieren Sie die enthaltenen Typ (erfordern eine generische Version, eine partielle Spezialisierung für std::vector
und ähnliche typename ...
Container und eine Spezialisierung für std::array
, andere Spezialisierungen können hinzugefügt werden) wie die folgende isCnt
template <typename>
struct isCnt : public std::false_type
{ };
// std::array case
template <template <typename, std::size_t> class C,
typename T, std::size_t N >
struct isCnt<C<T, N>> : public std::true_type
{ using containedType = T; };
// other container case
template <template <typename ...> class C,
typename T0, typename ... Ts>
struct isCnt<C<T0, Ts...>> : public std::true_type
{ using containedType = T0; };
Sie setData()
konstruieren können als
Vorlage folgt :: containedType> Leere SetData (C const & Daten) { // Code hier }
Beachten Sie, dass setData()
ist SFINAE aktiviert (oder deaktiviert) durch T = isCnt<C>::containedType
, ist, dass nur für Container zur Verfügung.
Nachstehend ist ein voll funktionierendes Beispiel
#include <array>
#include <vector>
#include <iostream>
#include <type_traits>
template <typename>
struct isCnt : public std::false_type
{ };
// std::array case
template <template <typename, std::size_t> class C,
typename T, std::size_t N >
struct isCnt<C<T, N>> : public std::true_type
{ using containedType = T; };
// other container case
template <template <typename ...> class C,
typename T0, typename ... Ts>
struct isCnt<C<T0, Ts...>> : public std::true_type
{ using containedType = T0; };
struct Test
{
template <typename C, typename T = typename isCnt<C>::containedType>
void SetData (C const & data)
{
if (std::is_same<T, int>::value)
std::cout << "- int case" << std::endl;
else if (std::is_same<T, float>::value)
std::cout << "- float case" << std::endl;
}
};
int main()
{
Test test;
std::vector<int> vector{ 1,2,3 };
std::array<float, 3> arr{ { 1.0f, 2.0f, 3.0f } };
test.SetData(vector); // print "int case"
test.SetData(arr); // print "float case"
//test.SetData(0); // compilation error
}
Sie werden nicht in der Lage sein, eine Vorlage bekommen sie alle als 'std :: array' nehmen verwendet einen nicht-Typ Template-Parameter. – NathanOliver
@KaiserJohaan - Antwort verbessert: Definition des Typs in 'isCnt' mit einem anderen Namen für' type' (das auch von 'std :: true_type' und' std :: false_type' übernommen wird), sagen wir 'containedType', ist es möglich um den SFINAE-Aktivierungs-/Deaktivierungsteil zu vereinfachen, der an "T" arbeitet, und die Verwendung von "std :: enable_if" mit dem Rückgabetyp zu vermeiden. – max66