2013-06-23 7 views
3

Я хочу реализовать контейнер, который может принимать начальный список элементов, предоставляя конструктору последовательность значений.Ошибка аргумента аргумента шаблона/замещения

9 template <typename C, int max> 
10 struct c_array 
11 { 
12  typedef C value_type; 
13 
14  typedef C* iterator; 
15  typedef const C* const_iterator; 
16 
17  typedef C& reference; 
18  typedef const C& const_reference; 
19 
20  c_array() { } 
21  template <class T> 
22   c_array(typename T::iterator begin,typename T::iterator end) 
23   { 
24   } 
25 
26  C v[max]; 
27  operator C*() { return v; } 
28 
29  reference operator[] (ptrdiff_t i) { return v[i]; } 
30  const_reference operator[] (ptrdiff_t i) const { return v[i]; } 
31 
32  iterator begin() { return v; } 
33  const_iterator begin() const { return v; } 
34 
35  iterator end() { return v+max; } 
36  const_iterator end() const { return v+max; } 
37 
38  size_t size() const { return max; } 
39 }; 
40 
41 int main(int argc, char** argv) 
42 { 
43  std::vector<int> myvector(10,10); 
44  c_array<int,10> myarray1(myvector.begin(),myvector.end()); 
     ... 

Я получаю следующее сообщение об ошибке при компиляции

... 
test.cc:56:61: error: no matching function for call to ‘c_array<int, 10>::c_array(std::vector<int>::iterator, std::vector<int>::iterator)’ 
test.cc:56:61: note: candidates are: 
test.cc:22:9: note: template<class T> c_array::c_array(typename T::iterator, typename T::iterator) 
test.cc:22:9: note: template argument deduction/substitution failed: 
test.cc:56:61: note: couldn't deduce template parameter ‘T’ 
... 

Спасибо заранее,

ответ

6

В декларации

template <class T> 
c_array(typename T::iterator begin,typename T::iterator end) 

T используется таким образом, называется «не -избранный контекст ". Нет разумного способа, если вы передадите аргументы типа MyCustomIter, чтобы компилятор угадал, какой тип T может содержать typedef MyCustomIter iterator;. Поэтому C++ Standard говорит, что компиляторы не должны даже пытаться.

Вместо этого вы можете просто написать функцию, чтобы взять любой тип и предположить/документ, что он должен быть итератором.

template <class InputIter> 
c_array(InputIter begin, InputIter end) { 
    std::copy_n(begin, max, v); 
} 
+0

+1 для того, чтобы четко объяснить, почему вам нужно это изменение. Дополнительное примечание, которое может быть или не быть новым для OP: для обычных функций это не обязательно является проблемой, если вычет шаблона не может быть успешным, так как до сих пор можно явно указать аргументы шаблона. Такой шаблон не существует для шаблонных конструкторов, поэтому шаблонный конструктор, где аргументы шаблона не могут быть выведены, никогда не будет вызываемым. – hvd

+0

+1 Большое спасибо –