2015-04-13 3 views
7

я испытывал некоторые из инструментов в type_traits заголовке над массивами 14 во время выполнения нового C++ размера, рассмотрит код ниже:время выполнения размера массивов и указатели-распад

int g[]{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}; 

template <typename T> void print(T &t) 
{ 
    std::cout << "Type id: " << typeid(T).name() << '\n'; 
    std::cout << "is_array: " << std::is_array<decltype(T)>::value << '\n'; 
    std::cout << "is_pointer: " << std::is_pointer<decltype(T)>::value << '\n'; 
    std::cout << "extent:  " << std::extent<decltype(T)>::value << '\n'; 
} 

int main() 
{ 
    print(g); 
    return 0; 
} 

массив статического размера, g возвращается следующий вывод:

Type id: A11_i 
is_array: 1 
is_pointer: 0 
extent:  11 

unmangled имя A11_i Я предполагаю, что это rray из элементов типа INT, так что все правильно здесь, но с новым кодом:

void f(std::size_t s) 
{ 
    int a[s]; 
    print(a); 
} 

int main() 
{ 
    f(5); 
    return 0; 
} 

Я получаю сообщение об ошибке:

In function 'void f(std::size_t)': 
error: no matching function for call to 'print(int [s])' 

note: candidate is: 
note: template<class T> void print(T&) 
note: template argument deduction/substitution failed: 
note: variable-sized array type 'int [s]' is not a valid template argument 

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

template <typename T> void print(T *&t) 

С подобными результатами:

In function 'void f(std::size_t)': 
error: no matching function for call to 'print(int [s])' 

note: candidate is: 
note: template<class T> void print(T*&) 
note: template argument deduction/substitution failed: 
note: mismatched types 'T*' and 'int [s]' 

И я заметил, что переменный размер в массиве выполнения размера, кажется, привязан к типу (вместо mismatched types 'T*' and 'int [5]' мы получаем mismatched types 'T*' and 'int [s]'), это выглядит довольно странно.

Итак, в чем вопрос?

  • Почему я не получаю разложение от массива до указателя в этом массиве размера времени выполнения?
  • Переменная переменная используется для определения размера массива размера времени выполнения типа массива размера времени выполнения или я неправильно понимаю ошибку?
+1

Обратите внимание, что вы используете расширение VLA с 'Int а [s];' – Jarod42

+0

Много флагов компилятора или норм кода запрещают использовать массив размера во время выполнения. (Я знаю, что G ++ с предупреждающими флагами запрещает его, например). Возможно, ваш компилятор отказывается использовать его в качестве шаблона. – Aracthor

+5

Чтобы развернуть комментарий Jarod42, были предложены массивы размера времени выполнения, но не были включены в окончательный стандарт C++ 14. – user2079303

ответ

3

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

§14.8.2.1 Выведение аргументы шаблона из вызова функции [temp.deduct.call]

1 Шаблон вывод аргумента делается путем сравнения каждой функции шаблона параметр типа (назовем его P) с типом соответствующего аргумента вызова (назовите его A), как описано ниже. [...]

2 Если P не является тип ссылки:

  • Если A является типом массива, тип указателя производится с помощью массива к-указателя стандартного преобразования (4.2) используются вместо A для Тип вычета; в противном случае,
  • [...]
Смежные вопросы