2017-01-24 2 views
14

Мое понимание о Template argument deduction for class templates предложение было гомогенизировать поведение функций шаблона и классов шаблонов в контекстах вычета. Но я думаю, что я должен был что-то не понимать.C++ 17 класс шаблон частичный вывод

Если у нас есть этот шаблон объект:

template <std::size_t S, typename T> 
struct test 
{ 
    static constexpr auto size = S; 
    using type_t = T; 

    test(type_t (&input)[size]) : data(input) {} 
    type_t (&data)[size]{}; 
}; 

Я предпочитаю использовать вспомогательную функцию в качестве синтаксического для создания test объектов:

template <std::size_t S, typename T> 
test<S, T> helper(T (&input)[S]) { return input; } 

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

int main() 
{ 
    int buffer[5]; 

    auto a = helper<5, int>(buffer); // No deduction 
    auto b = helper<5>(buffer);  // Type deduced 
    auto c = helper(buffer);   // Type and size deduced 

    std::cout << a.size << b.size << c.size; 

    return 0; 
} 

код выше выходов 555 как и ожидалось. Я пробовал то же самое в Wandbox используя новую установку компилятора :

int main() 
{ 
    int buffer[5]; 

    test<5, int> a(buffer); // No deduction: Ok. 
    test<5> b(buffer);  // Type deduced: FAILS. 
    test c(buffer);   // Type and size deduced: Ok. 

    std::cout << a.size << b.size << c.size; 

    return 0; 
} 

Похожи аргументы шаблона дедукции для шаблонов классов работает только выводя все параметры, я Ожидал обоих поведения (вспомогательную функцию и класс шаблон), чтобы быть тем же, я что-то не понял?


В последних составителях в Wandbox Доступными является GCC 7.0.1 ГОЛОВКОЙ 201701 и лязга ГОЛОВКА 5.0.0 (ствол).

+2

Является 'type_t (и данные) [размер] {};' ссылка на массив? Является ли '{}' инициализатором? Скомпилирует ли это? Кроме того, * sintactic sugar * звучит довольно непослушным. :) – wally

+2

Обратите внимание, что [добавление явного * вычитающего руководства *] (http://melpon.org/wandbox/permlink/VEE5DyIE3w3LEGEX) не помогает.Я считаю, что частичный вывод не поддерживается, поскольку в стандарте определяются места размещения вычетов в терминах * имени шаблона * * (т. Е. Без синтаксиса '<...>' *). Поэтому 'test <5>' не является допустимым заполнителем вычетов. –

+0

@Muscampester 'type_t (& data) [size] {};' это ссылка на массив, да. '{}' Действительно инициализатор, и он компилирует [try it out!] (Http://melpon.org/wandbox/permlink/KCkDg5EEIKbZbPU3). О * синтаксическом сахаре * что я могу сказать ...: «(английский не мой родной язык, и я много ошибок!» –

ответ

11

От этого прекрасного trip report по Botond Балло:

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

// Would have deduced tuple<int, string, float>, 
// but tuple<int> is a well-formed type in and of itself! 
tuple<int> t(42, "waldo", 2.0f); 
+2

Я нахожу это рассуждение очень странным. Итак, в первую очередь у нас было 'std :: make_tuple (42,« waldo », 2.0f);« делали якобы все по-другому и учили людей, что неправильно указывать аргументы шаблона, когда они выводятся. Теперь, запретив это, мы делаем вывод для шаблона класса работать по-разному как функция (несогласованность) и блокировать массу допустимых вариантов использования (отличных от примера надуманного кортежа). – Predelnik

12

Похоже, здесь существует противоречие. Глядя на P0091R3, представляется очевидным, что частично с указанием параметров, как предполагается, будет разрешено:

Мы предлагаем, чтобы имя шаблона со ссылкой на шаблон класса в качестве простого-типа-спецификатор или с частично указанными аргументами явных шаблонов в двух контекстах:

Но фактических стандарты формулировки в том же предложении не предоставляет способ справиться с «частично переданными аргументами явных шаблонов». template-name как спецификатор простого типа не допускается иметь аргументы шаблона.

Так что, следуя самой спецификации, поведение компилятора представляется правильным.

+3

Да, эта статья, в частности, является довольно вопиющим случаем, когда автор не смог синхронизировать вводные части, поскольку редакция и дизайн были пересмотрены. К сожалению, результат является вводящим в заблуждение вводным разделом. –

+0

Хорошо, что у них есть другая встреча, прежде чем они захотят получить окончательное голосование. –

+1

@MikelF: Вы предполагаете, что они фактически разрешат частичную спецификацию. Несоответствие в написании предполагает, что это было то, что комитет избрал * remove *, а не оригинальный писатель просто делает ошибку в своих формулировках. –

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