Невозможно вывести тип в классе с конструктором, принимающим std :: array - PullRequest
0 голосов
/ 27 мая 2020

Я пытаюсь создать шаблонный класс, содержащий пары перечисление-строка, и не могу выполнить вывод типа. Со следующим кодом у меня две проблемы:

namespace {
template<typename T, size_t S>
using EnumStringArray = std::array<std::pair<T, const char*>, S>;
}

template<typename T, size_t S>
class EnumToString {
public:
    constexpr EnumToString(const EnumStringArray<T, S>& array) :
            _array(array)
    {}
private:
    EnumStringArray<T, S> _array;
};

template<typename T, size_t S>
EnumToString(const EnumStringArray<T, S>&) -> EnumToString<T, S>;

enum MyEnum {
    One, 
    Two
};

constexpr EnumToString enumStrings = {{{    //<---- does not compile without explicit types
        {One, "One"},
        {Two, "Two"}
}}};
  1. Почему компилятор не может самостоятельно вывести параметры EnumToString в конструкторе?
  2. Почему руководство пользователя по выводам не помогает?

Ответы [ 2 ]

1 голос
/ 27 мая 2020

{..} не имеет типа и не может быть выведено (кроме std::initializer_list<T> или T(&)[N]).

поэтому обычный конструктор или руководство по выводам здесь не помогают с CTAD.

0 голосов
/ 27 мая 2020

Причина, как упоминалось в @ Jarod42, заключается в том, что в C ++ инициализаторы скобок не имеют никаких типов и не могут быть выведены компилятором в контексте шаблонов. Причина этого кратко изложена здесь .

Чтобы исправить это, вы можете использовать переменную auto, чтобы определить тип, а затем передать его в метод шаблона.

auto x = {{One, "One"}, {Two, "Two"}};
// Now x has a type, you can pass it to a template function. 
...