2016-10-08 3 views
1

В следующем коде:Вывести std :: размер массива?

template<size_t N> 
int b(int q, const std::array<int, N>& types) 
{ 
    int r = q; 
    for (int t : types) 
    { 
     r = r + t; 
    } 
    return r; 
} 

int main() 
{ 
    b<2>(9, { 2,3 }); 
} 

Как я могу избежать того, чтобы указать 2 в вызове б для N? Почему этот тип не может быть автоматически выведен? Без этого я получаю сообщение об ошибке:

'b': no matching overloaded function found 'int b(int,const std::array &)': could not deduce template argument for 'N'

ответ

2

Вывод аргумента шаблона основан на прямом сопоставлении типов между фактическим аргументом и формальным аргументом. Фактический аргумент - это список инициализаторов. Он не соответствует типу array (в лучшем случае он может соответствовать внутреннему необработанному массиву в std::array, но языковые правила этого не поддерживают).

Вместо этого вы можете просто использовать необработанный массив, а именно:

#include <stddef.h> 
#include <array> 

template<size_t N> 
int b(int q, int const (&types)[N]) 
{ 
    int r = q; 
    for (int t : types) 
    { 
     r = r + t; 
    } 
    return r; 
} 

int main() 
{ 
    b(9, { 2, 3 }); 
} 

Или, если вы абсолютно не нужно N во время компиляции, вы можете использовать std::initializer_list.

Существует также много других возможных подходов (например, функция вариационного шаблона или определение оператора для создания std::vector), но трудно сказать, что подойдет вашей нераскрытой цели.

+0

Ах извините, моя цель состоит в том, чтобы передать массив целых чисел, которые будут проверены против ИНТА MTYPE образом структур, сырой массив кажется хорошим достаточно для того, что я делаю в любом случае – paulm

1

Для выведения std::array размера можно использовать общие лямбды (C++ 14):

auto b = [](int q, const auto& types) { 
    int r = q; 
    for (int t : types) 
    { 
     r = r + t; 
    } 
    return r; 
}; 

int main() { 
    std::array<int, 2> arr = {{2,3}}; 
    b(9, arr); 
} 

Когда std::make_array (это в библиотеке Основы ТС) будут получать реализованы составителями (или вы будете использовать some own реализацию этого) вы не должны будете также передать размер массива при построении, просто используйте

b(9, std::make_array(2,3)); 
+4

Читатели должны заметить, что 'auto' здесь не делает ничего, что обычный' template' не будет делать. Этот код работает, потому что тип фактического аргумента указан как 'std :: array', а не из-за' auto'. При этом «main» этого ответа будет также работать определение OP 'b'. –

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