2016-05-01 7 views
1

Ich versuche, die Art der Elemente zu beschränken, wie std::array<std::string,N>> zu verarbeiten, aber Template Substitution nicht für N.Vorlage: Der Abzug von Array-Größe gescheitert

main.cpp:10:1: note: template argument deduction/substitution failed: 
main.cpp:31:34: note: couldn't deduce template parameter 'N' 
    print(word.begin(),word.end()); 

Mein Versuch, wie folgend.

#include <iostream> 
#include <string> 
#include <vector> 
#include <array> 
#include <boost/range/iterator_range.hpp>  

template<typename ForwardIterator,std::size_t N> 
typename std::enable_if<std::is_same<typename ForwardIterator::value_type,std::array<std::string,N> >::value >::type 
print(ForwardIterator begin, ForwardIterator end) 
{ 
    for(auto const & arr : boost::make_iterator_range(begin,end)) 
    { 
     for(auto const & item : arr) 
     { 
      std::cout<<item<<' '; 
     } 
     std::cout<<'\n'; 
    } 
} 

int main() 
{ 
    std::vector<std::array<std::string,2>> word; 
    word.push_back({{"hello","Hi"}}); 
    word.push_back({{"b","bye"}}); 
    print(word.begin(),word.end()); 
} 

Demo on Coliru

Antwort

3

Sie haben Ihr Konzept zu ändern und statt den Typen auf ein Array von einer unbekannten Größe zu vergleichen (das heißt, kann der Compiler nicht sagen, was N wou im Kopf hat), überprüfen, ob der Typ selbst als Array abgeleitet:

#include <array> 
#include <iterator> 
#include <type_traits> 
#include <string> 

template <typename T, typename A> 
struct is_std_array : std::false_type {}; 

template <typename T, std::size_t N> 
struct is_std_array<T, std::array<T,N>> : std::true_type {}; 

template<typename ForwardIterator> 
auto print(ForwardIterator begin, ForwardIterator end) 
    -> typename std::enable_if< 
      is_std_array<std::string, typename std::iterator_traits<ForwardIterator>::value_type>::value 
     >::type 
{ 

} 

auch nicht die Verwendung von std::iterator_traits.

DEMO

+0

ist Danke ... Es hat funktioniert !! – gjha

1

(Das ist nicht wirklich eine vollständige Antwort, nur ein Versuch, intuitiv zu erklären, warum der gegenwärtige Ansatz nicht funktioniert.)

Es ist, weil Sie ihm jede Chance nicht geben ableiten N. Die N erscheint nur einmal in der Signatur, und das ist Test für die Gleichheit. Dies zwingt die Typen nicht dazu, einander gleich zu sein.

Als wirklich einfaches Beispiel, würde man nicht erwarten, dass dieser Code Tint zwingen würde:

template<typename T> 
typename std::enable_if<std::is_same<T,int >::type 
void foo(T) { 
} 

(Auch wird der Rückgabetyp foo hier nicht T oder int sein würde Es wird ein spezieller boolescher Typ sein.Wieder wahrscheinlich nicht, was Sie wollen.)

Letztlich, was willst du hier? Ich schätze, dass Sie sicherstellen wollen, dass es nur mit Iteratoren aufgerufen wird, deren Werttyp ein

+0

Ja, Sie sind richtig 'Ich möchte sicherstellen, dass es nur mit Iteratoren aufgerufen wird, deren Werttyp ein std :: array' ist – gjha

Verwandte Themen