0

I have a vector<int> and functions that only accepts a vector<unsigned int> references.I know that I could change/template the functions(and this is likely the best thing to do), but ideally I would have a way to cast/convert the vector<unsigned int> reference to a vector<int> reference. I know that all values in the vector are positive, and non of the functions will even come close to overflowing the integers.

I have tried using static_cast<vector<int>> but that doesn't work.

Edit:

I say cast/convert of the references but I am not looking to create a new copy and reference that.

7
  • 3
    Casting pointers to unrelated types is undefined behavior (type punning). You should not do it.
    – Marek R
    Commented Apr 13, 2023 at 11:27
  • 2
    There are two ways to solve this: Create a copy of the original vector, with the correct type; Or use a std::vector<unsigned int> to begin with, no copying or conversion needed. Commented Apr 13, 2023 at 11:29
  • I know that I could change/template the functions(and this is likely the best thing to do) Yes, do that. The other way will end in tears.
    – Eljay
    Commented Apr 13, 2023 at 11:43
  • 1
    IMO, a function that only accepts a vector<unsigned int> is bad by design. At least, the function should be a function template, where the vector value type is a template parameter. Even a better approach would be to use iterators as input parameters, or something as std::span. Commented Apr 13, 2023 at 11:57
  • @Daniel Langr, The values are 28 bit-bitflags. The actual hardcoded vector holds a uint32_t. I get the vector<int32_t>& from a libary. I think that it was a weird design choise to use a signed type for the bitflags. (It does this because when ran in debug mode, negative values are used for errors indication. This isnt a great reason in my opinion, but its what I will have to deal with.)
    – r123
    Commented Apr 13, 2023 at 12:53

4 Answers 4

3

you cannot cast, but you mention conversion is an option, which is easily done like this:

void foo(const std::vector<unsigned int>& data)
{
     // ...
}

void main()
{
    std::vector<int> vec;
    foo({ vec.begin(), vec.end() });
}
2
  • Works for int/unsigned int because there is an implicit conversion. Commented Apr 13, 2023 at 11:40
  • Thank you for your response. I said cast/convert of the references but I am not looking to create a new copy and reference that.
    – r123
    Commented Apr 13, 2023 at 11:53
1

Use std::transform to make a new copy of the vector with converted values. You cannot and should not reinterpret_cast to cast between unrelated types (std::vector<int> != std::vector<unsigned int>)

#include <vector>
#include <algorithm>
#include <iterator>
#include <iostream>

int main()
{
    std::vector<int> values{ 1,2,3,4,5 };
    std::vector<unsigned int> converted_values;

    // avoid raw for loops
    std::transform(values.begin(), values.end(), std::back_inserter(converted_values), [](const int value)
    { 
        return static_cast<unsigned int>(value); 
    });

    for (const auto& value : convered_values)
    {
        std::cout << value << " ";
    }

    return 0;
}
0

One C++20,23 approach would be to use ranges:

#incluce <ranges>
template<typename result>
constexpr auto cast_trans = std::views::transform( // C++20
            [](auto const& x)
            { return static_cast<result>(x); });

std::vector<int> vint;
auto ruint = vint | cast_trans<unsigned>; 

auto vuint = ruint | std::ranges::to<std::vector>; // C++23

Ranges library has got a lot explore.

-1

There is no cast that does not result in undefined behaviour, but if you really want to do this then this will probably work in practise

*reinterpret_cast<vector<unsigned int>*>(&vec)

Create a pointer, cast the pointer, then dereference. I used to do this sort of thing all the time when I was a C programmer.

Really though, you should not do this.

4
  • 1
    This should not be an acceptable answer. It is a programming habit that will set you up to fail at some point. Commented Apr 13, 2023 at 11:45
  • Ty, the program is only a quick proof-off-concept and not fital at all, so I will accept undefined behaviour for now. I had already tried something similar but using reinterpret_cast with references(also works) but I had forgotten to have that function return a reference(facepalm).
    – r123
    Commented Apr 13, 2023 at 11:46
  • @PepijnKramer Kramer. I think that this answer is clear on this being undefined and dangerous behaviour.
    – r123
    Commented Apr 13, 2023 at 11:49
  • Sure it is clear that it is dangerous, doubly so because "C" is not "C++". Commented Apr 13, 2023 at 14:32

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.