Руководство по частичному выводу C++17

Я пытаюсь написать руководство по выводу, которое обнаруживает только одно из множества typename из данного аргумента конструктора и требует от пользователя ввода intsize вручную

template <int size, typename T>
struct Board
{
            array<array<T, size>, size> values;

            explicit Board(const vector<T>& raw_values){

            }
};
template <int size, typename T> Board(const vector<T>&) -> Board<int size, T>;

Идея выше заключается в том, что пользователь все равно должен быть вынужден войти "int size"аргумент шаблона, но"typename T"должно быть выведено из аргумента конструктора, это возможно?

После правильной спецификации, это то, как метод должен быть вызван

auto b = Board<3>(initialStateVector);

В настоящее время мне необходимо войти вот так;

auto b = Board<3, int>(initialStateVector);

Так что в принципе я хочуint"выше следует вывести из данного initialStateVector, который имеет тип

const vector<int>& raw_values

1 ответ

Решение

Идея выше состоит в том, что пользователь все еще должен быть вынужден ввести аргумент шаблона "int size", но "typename T" должно быть выведено из аргумента конструктора, возможно ли это?

В соответствии с примечанием (и следующими примерами) на этой странице cppreference

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

нет, это невозможно (не в C++17; мы можем надеяться на будущие версии стандарта).

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

Я имею в виду что-то следующее (используя std::size_t для размера, как в std::array и почти все STL)

template <std::size_t S, typename T>
Board<S, T> make_Board (std::vector<T> const & v)
 { return {v}; }

// ...

auto b = make_Board<3>(initialStateVector);

это должно работать также в C++11.

Я придумал обходной путь, используя объект подсказки размера

template<int size>
struct SizeHint {};

Ваш класс примет это как дополнительный аргумент конструктора:

Board(SizeHint<size>, const std::vector<T>& raw_values)

Вы вызываете конструктор так:

auto b = Board(SizeHint<2>{}, v);

Бонус

Этот подход также работает для подсказок типа (моя первоначальная мотивация, как я нашел эту ветку):

template<typename T>
struct TypeHint{};

template<typename Result, typename T>
struct S {
    S(TypeHint<Result>, T arg) : t{arg}{}
    Result r() {return t;}
    T t;
};

#include <iostream>
int main() {
    S s{TypeHint<int>{}, 5.7};
    std::cout << s.r() << std::endl;
}

Это также можно использовать в сочетании с вариативными шаблонами:

template<typename Result, typename... Args>
struct S {
    S(TypeHint<Result>, Args... args) : t{args...}{}
    std::tuple<Args...> t;
};
Другие вопросы по тегам