martinmoene / variant-lite

variant lite - A C++17-like variant, a type-safe union for C++98, C++11 and later in a single-file header-only library
Boost Software License 1.0
239 stars 26 forks source link

max_index defined as data_size? #33

Closed KarimLUCCIN closed 5 years ago

KarimLUCCIN commented 5 years ago

https://github.com/martinmoene/variant-lite/blob/8a5f0665f76160b6d038537b37771bd708d45de0/include/nonstd/variant.hpp#L1475

Was this line meant to be data_size, or instead the maximum number of types in the variant? It seems that the code below will cause a bad_access, because int is at index 4, which is also the data_size of the variant:


template<size_t i>
class N{int k;};

using MyVar = nonstd::variant<N<0>, N<1>,N<2>,N<3>, int>;

int main()
{
    MyVar a(2);

    nonstd::visit([](const auto& a) {
        std::cout << "Val: " << sizeof(decltype(a)) << std::endl;
    }, a);

    return 0;
}
martinmoene commented 5 years ago

Thanks @KarimLUCCIN ,

Good catch.

max_index() means _max_alternativeindex().

Its implemention is wrong, and it is used erroneously and superfluously in this and this check for invalid access.

The bad access can be revealed more directly via get<type>(var):

using nonstd::get;
using variant_t = nonstd::variant<N<0>,N<1>,N<2>,N<3>, std::int32_t>;

try
{ 
    (void) get<std::int32_t>( variant_t( 13 ) ) ); 
}
catch( std::exception const & e )
{
    std::cout << "Error: '" << e.what() << "'\n";
}

yielding: Error: 'bad variant access'

KarimLUCCIN commented 5 years ago

Thanks for the fix!