Невозможно вывести нетипичный параметр шаблона для параметра функции - PullRequest
2 голосов
/ 03 июня 2019

Это может быть что-то действительно простое, но я не могу понять, почему этот код не компилируется

#include <type_traits>

template <std::size_t Size, std::size_t Align>
void foo(std::aligned_storage_t<Size, Align>&) {}

int main() {
    auto storage = std::aligned_storage_t<100, 8>{};
    foo(storage);
}

(https://wandbox.org/permlink/PdBwAWVh6N9rkTE2)

Как я могу заставить это работать? И почемуне компилируется ли это?


Сценарий использования состоит в том, что foo() представляет собой набор перегрузок для несвязанных типов, таких как aligned_storage_t, int, double и т. д. И экземпляр aligned_storage_tпредставляет память, которую foo() знает, как интерпретировать и использовать.

Ответы [ 2 ]

3 голосов
/ 03 июня 2019

Это не работает, потому что std::aligned_storage_t не является классом, это псевдоним типа для некоторого типа, определенного реализацией.На самом деле то, что у вас есть:

template <std::size_t Size, std::size_t Align>
void foo(typename std::aligned_storage<Size, Align>::type);

Size и Align не может быть выведено из этого, поскольку это не выводимый контекст.Вам нужно заменить оба экземпляра std::aligned_storage_t на std::aligned_storage.Тогда, если вам нужен выровненный тип, вы получите доступ к нему с помощью ::type.

0 голосов
/ 03 июня 2019

Size и Align не вычитаются с std::aligned_storage<Size, Align>::type.

Вы можете использовать sizeof / alignof для получения (почти) начального значения:

template <typename T>
void foo(const T&)
{
    constexpr std::size_t size = sizeof(T);
    constexpr std::size_t alignment = alignof(T);

    std::cout << size << " "<< alignment << std::endl;
}

Демо (получил размер 104 вместо ввода 100 из-за выравнивания для вашего примера)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...