C ++ хранит массив необработанных символов в кортеже - PullRequest
0 голосов
/ 28 октября 2019

Почему я не могу назначить символьные массивы в std::pair или boost::tuple?

typedef std::pair<int, char [5]> tuple_type;
tuple_type(5, "abcd");

Приведенное выше сообщение приводит к следующей ошибке.

error: no matching function for call to ‘std::pair<int, char [5]>::pair(int, const char [5])’
   51 |     tuple_type(5, "abcd");

Даже если я использую std::pair<int, const char [5]>, ошибка сохраняется

error: no matching function for call to ‘std::pair<int, const char [5]>::pair(int, const char [5])’

Единственное решение - либоиспользуйте const char* или std::string Но в моей настоящей проблеме я упаковываю набор переменных аргументов в кортеж.

template <typename Ret, typename CallableT, typename... Args>
struct returned_: public Ret{
    typedef boost::hana::tuple<Args...> tuple_type;
    tuple_type _tuple;
    const CallableT& _call;

    returned_(const CallableT& call, const Args&... args): _call(call), _tuple(args...), Ret(_tuple){}
    // ...
};

Так что, если код пользователя не преобразуется в const char* или не заключает в std::stringшаблон returned_ приведет к ошибкам времени компиляции. Какое решение не заставляет пользователя не передавать строковый литерал C?

Ответы [ 3 ]

3 голосов
/ 28 октября 2019

В выражениях списка аргументов

tuple_type(5, "abcd");

строковый литерал "abcd" неявно преобразуется в тип const char *. И массивы не имеют оператора присваивания и, более того, когда указатель используется в качестве инициализатора.

0 голосов
/ 28 октября 2019

Как я уже упоминал в этом вопросе, я не хочу заставлять пользователя передавать только std::string или приводить к const char*. Я иду в направлении, указанном @ NathanOliver

template <typename T>
struct trans{
    typedef typename std::decay<T>::type type;
};
template <int N>
struct trans<char[N]>{
    typedef const char* type;
};

template <typename T>
using trans_t = typename trans<T>::type;

Приведенный выше шаблон преобразует char[N] в const char*.

template <typename Ret, typename CallableT, typename... Args>
struct returned_: public Ret{
    typedef boost::hana::tuple<trans_t<Args>...> tuple_type; // trans_t will convert char[N] to const char*
    tuple_type _tuple;
    const CallableT& _call;

    returned_(const CallableT& call, const Args&... args): _call(call), _tuple(args...), Ret(_tuple){}
    // ...
};
0 голосов
/ 28 октября 2019

C-массив не копируется, вы можете заключить его в структуру как std::array, которая копируется.

...