2015-05-12 2 views
2

У меня есть пример кода, который использует программирование шаблонов, он отлично работает на linux. Но когда я пытаюсь привести его к окнам с visual studio 12, я получил ошибку компиляции о выводе аргумента шаблона. Здесь доля кода, который вызывает ошибку:C++ - Не удалось вывести аргумент шаблона

template <int I> 
class assign_array 
{ 
public: 
    template <typename U, unsigned N> 
    static inline void run(improved_builtin<U, N>& a, const U b[N]) 
    { 
     // do sth 
    } 
}; 

template <template <int> class A, int I, int E> 
struct loop_iter 
{ 
    template <typename U, typename V> 
    static inline void iter(U& a, V& b) 
    { 
     A<I>::run(a, b); // get error here 
    } 
}; 

template <typename T, unsigned N> 
improved_builtin<T, N>::improved_builtin(const T v[N]) 
{ 
    loop_iter<assign_array, 0, N - 1>::iter(*this, v); 
    return; 
} 

ошибка происходит на :: Run (а, б) => assign_array < 0> :: Run (improved_builtin &, Const U [N]) ': не удалось вывести шаблонный аргумент для' const U [N] 'from' const int * '

И я заметил что-то странное в сообщении об ошибке, которое улучшено_builtin. В классе assign_array подпись первого аргумента должна быть улучшена_builtin. Я понятия не имею, почему США появляются там. Кто-нибудь знает об этой ошибке?

+1

Можете ли вы опубликовать пример, который будет скомпилирован под Linux? – Petr

+0

@Petr, код на самом деле тот же для linux и windows! Когда я вызывал функцию улучшенное_builtin (const T v [N]), он вызывает ошибку компиляции в окнах. Но в Linux он компилируется и работает нормально. – Bent

+2

Используйте 'std :: array ' вместо массива C. – Johny

ответ

3

Когда вы передаете массив в функцию, он будет распадаться на указатель, поэтому вы потеряете размер, из которого вы пытаетесь вывести аргумент шаблона. Передача массива по ссылке сохранит тип и позволить вычет иметь место:

static inline void run(improved_builtin<U, N>& a, const U (&b)[N]) 
//          take by reference^

Причина, по которой г ++ (и лязг) способны скомпилировать пример в любом случае является то, что они используют свой improved_builtin аргумент вывести тип от U и значение N вместо типа массива. По какой-то причине VS2012 этого не делает и пытается вывести из массива, что недействительно, потому что оно заглохло. Если у вас не было этого аргумента improved_builtin, ваш пример вообще не компилируется.

+0

вот что я думаю! msvc не удалось вывести аргумент, потому что он неверно признает аргумент Improved_builtin! Если вы заметили ошибку сообщения, это должно быть улучшено_builtin вместо улучшенного_builtin . – Bent

1

Решение, как упомянуто TartanLlama и Johny в комментариях. Но выбрал soltution TartanLlama в потому что это легче изменить:

"Изменение improved_builtin и запустить взять массив по ссылке, а не может работать: сопзЬ T (& v) [N] и Const U (& б) [N]"

Это потому, что передача по ссылке помогает нам сохранить размер массива. Но я до сих пор не знаю, почему он может компилироваться и запускаться с использованием g ++.

Смежные вопросы