Почему я не могу static_cast кортеж, содержащий void *, к кортежу, содержащему char *? - PullRequest
0 голосов
/ 29 ноября 2018

В приведенном ниже коде я пытаюсь static_cast a std::tuple<void*, size_t> до std::tuple<char*, size_t>:

#include <tuple>

int main() {
  char data[] = {'a', 'b', 'c'};
  size_t data_len = 3;

  const std::tuple<void*, size_t> a{static_cast<void*>(data), data_len};
  const std::tuple<char*, size_t> b =
      static_cast<const std::tuple<char*, size_t>>(a);
  printf("a's first element is %p\n", std::get<0>(a));
  printf("b's first element is %p\n", std::get<0>(b));
}

Этот код не компилируется с g++ -std=c++17 или clang -std=c++17 (споследние версии GCC и Clang).В обоих случаях компилятор указывает, что статическое приведение невозможно.Вот пример ошибки от clang:

main.cc:9:13: error: no matching conversion for static_cast from 'const std::tuple<void *, size_t>' (aka 'const tuple<void *, unsigned long>') to 'const std::tuple<char *, size_t>'
      (aka 'const tuple<char *, unsigned long>')
            static_cast<const std::tuple<char*, size_t>>(a);
            ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Учитывая, что void* может быть от static_cast до char*, разве не может быть также возможно static_cast a std::tuple<void*, size_t>к std::tuple<char*, size_t>?Это просто упущение в дизайне STL или есть какая-то основная причина для этого?

Я столкнулся с этой проблемой, пытаясь найти основную причину этого вопроса StackOverflow .

Я пытаюсь уйти от этого вопроса: «Да, это странно, вы должны отправить тщательно сформулированное письмо в комитет по стандартам C ++ с предложением исправить это в будущем стандарте C ++» или «нет, не имеет смысла хотеть эту функцию, потому что X и Y ".

1 Ответ

0 голосов
/ 29 ноября 2018

Один из способов обойти это - предоставить промежуточный класс, который может обрабатывать для вас преобразование из std::tuple<void*, size_t> в std::tuple<char*, size_t>:

class TupleConverter : public std::tuple<char*, size_t> {
public:
  TupleConverter(const std::tuple<void*, size_t>& t) : std::tuple<char*, size_t>(
      static_cast<char*>(std::get<0>(t)), std::get<1>(t)) {}
};

Затем вы можете использовать его следующим образом:

const std::tuple<char*, size_t> b =
    static_cast<const TupleConverter>(a);
...