In the below code, I'm trying to static_cast
a std::tuple<void*, size_t>
to a 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));
}
This code does not compile with g++ -std=c++17
or clang -std=c++17
(with recent GCC and Clang versions). In both cases, the compiler indicates that the static cast can't be done. Here's an example error from 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);
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Given that a void*
can be static_cast
to a char*
, shouldn't it also be possible to static_cast
a std::tuple<void*, size_t>
to a std::tuple<char*, size_t>
? Is this just an oversight in the design of the STL or is there some underlying reason for it?
I ran into this issue while trying to find the root cause for this StackOverflow question.
What I'm trying to get out of this question is either "yes, that's weird, you should send a carefully worded email to the C++ standards committee suggesting that they fix this in a future C++ standard" or "no, it doesn't make sense to want this feature because X and Y".
One way to work around this is to provide an intermediate class that can handle the conversion from
std::tuple<void*, size_t>
tostd::tuple<char*, size_t>
for you:Then you can use it as follows: