Skip to content

Conversation

@MostafaNanticock
Copy link
Contributor

Description

We are using variant-lite in a project alongside tl::optional and other header-only C++11+ compatibility libraries. To provide a unified interface for downstream users, we expose them under a std_compat namespace:

namespace std_compat
{
    template <class T>
    using optional = tl::optional<T>;

    using tl::bad_optional_access;
    using tl::in_place_t;
    using tl::in_place;
    using tl::nullopt;
    using tl::nullopt_t;
    using tl::make_optional;
    using tl::swap;
}
namespace std_compat
{
    template <class... Types>
    using variant = nonstd::variant<Types...>;

    using nonstd::bad_variant_access;
    using nonstd::get;
    using nonstd::get_if;
    using nonstd::holds_alternative;
    using nonstd::visit;
    using nonstd::variant_npos;
    using nonstd::variant_size;
    using nonstd::variant_size_v;
    using nonstd::variant_alternative;
    using nonstd::variant_alternative_t;
}

Problem

  1. monostate conflicts:
    Both tl::optional and variant-lite require a monostate type.
    On MSVC 17.10.35122 (with C++17 enabled), the CRT also provides std::monostate.
    This results in three different monostate definitions that are not interchangeable, causing compilation errors when the libraries are used together.

  2. bad_variant_access mismatch:
    The MSVC CRT provides std::bad_variant_access.
    variant-lite uses its own nonstd::bad_variant_access.
    Third-party code using our std_compat::variant must catch both exceptions to be safe, which is error-prone and unintuitive.

Proposed solution:

Add configuration macros to variant-lite to allow users to override the monostate and bad_variant_access implementations with their own (or the standard library’s) versions.

For example:

#ifdef variant_CONFIG_BAD_VARIANT_ACCESS
using variant_CONFIG_BAD_VARIANT_ACCESS;
#else
class variant_nodiscard bad_variant_access : public ::std::exception
{
public:
#if variant_CPP11_OR_GREATER
    virtual const char* what() const variant_noexcept variant_override
#else
    virtual const char* what() const throw()
#endif
    {
        return "bad variant access";
    }
};
#endif
#ifdef variant_CONFIG_MONOSTATE
using variant_CONFIG_MONOSTATE;
#else
class monostate {};
#endif

Benefits:

  • Avoids duplicate/conflicting type definitions when integrating with other compatibility libraries.
  • Allows seamless use of the standard library’s monostate and bad_variant_access when available.
  • Reduces exception-handling boilerplate for downstream users.
  • Keeps variant-lite flexible without breaking existing behavior.

If this approach does not conflict with any existing design decisions or constraints in variant-lite, I’m happy to prepare and submit the implementation as a PR.

Introduced variant_CONFIG_MONOSTATE that users can set its value if they want variant-lite to use it instead of its own monostate class
Introduced variant_CONFIG_BAD_VARIANT_ACCESS that users can set its value if they want variant-lite to use it instead of its own bad_variant_access class
@martinmoene
Copy link
Collaborator

Note: continuation of optional-lite issue 82.

@MostafaNanticock
Copy link
Contributor Author

@martinmoene
These failing builds are failing on the master branch too, what should i do?
image
image

@martinmoene
Copy link
Collaborator

martinmoene commented Sep 22, 2025

Observations:

MSVC VS2019, VS2022 do work locally using:

CMD variant> cmake -S . -B build -D VARIANT_LITE_OPT_SELECT_NONSTD=ON  -D VARIANT_LITE_OPT_BUILD_TESTS=ON  -D VARIANT_LITE_OPT_BUILD_EXAMPLES=OFF
CMD variant> cmake --build build --config Release -j 4

It's not clear to me what difference there is with GitHub Actions VS2022 that result in the latter to error on compilation.
Removing VS2019 (windows-2019) from GitHub Actions is in the works (nonstd-lite-project issue 76).

Macros variant_CONFIG_BAD_VARIANT_ACCESS and variant_CONFIG_MONOSTATE are to be mentioned in Readme section Synopsis: Configuration macros.

I'll continue later as to 'not disprove' the viability of the concept to myself.

Added `variant_CONFIG_BAD_VARIANT_ACCESS` and `variant_CONFIG_MONOSTATE` to the Synopsis: Configuration macros section
@MostafaNanticock
Copy link
Contributor Author

Observations:

MSVC VS2019, VS2022 do work locally using:

CMD variant> cmake -S . -B build -D VARIANT_LITE_OPT_SELECT_NONSTD=ON  -D VARIANT_LITE_OPT_BUILD_TESTS=ON  -D VARIANT_LITE_OPT_BUILD_EXAMPLES=OFF
CMD variant> cmake --build build --config Release -j 4

It's not clear to me what difference there is with GitHub Actions VS2022 that result in the latter to error on compilation. Removing VS2019 (windows-2019) from GitHub Actions is in the works (nonstd-lite-project issue 76).

I'm using VS2022 locally and i tried to run the tests the same way you mentioned and it is actually failing.

specifically this is the error that i'm getting
image
I'm not really sure why is that and i tried to trace out what exactly is the ambiguous thing that the compiler is complaining about, but i couldn't figure out what exactly is going on.

I can take a deeper look into this later if you want, for now i will just leave the full error message that i'm getting from MSVC here because for some reason it's more readable and way shorter than the one from the CI/CD pipeline

C:\Users\hp\source\repos\variant-lite\include\nonstd/variant.hpp(2594): error C2666: 'nonstd::variants::detail::TX<nonstd::variants::detail::S2>::operator ==': overloaded functions have similar conversions
C:\Users\hp\source\repos\variant-lite\include\nonstd/variant.hpp(667): note: could be 'bool nonstd::variants::detail::TX<nonstd::variants::detail::S2>::operator ==(const T &) const'
        with
        [
            T=nonstd::variants::detail::S2
        ]
C:\Users\hp\source\repos\variant-lite\include\nonstd/variant.hpp(667): note: or 'bool nonstd::variants::detail::TX<nonstd::variants::detail::S2>::operator ==(const T &) const' [synthesized expression 'y == x']
        with
        [
            T=nonstd::variants::detail::S2
        ]
C:\Users\hp\source\repos\variant-lite\include\nonstd/variant.hpp(2594): note: while trying to match the argument list '(const nonstd::variants::detail::TX<nonstd::variants::detail::S2>, const nonstd::variants::detail::TX<nonstd::variants::detail::S2>)'
C:\Users\hp\source\repos\variant-lite\include\nonstd/variant.hpp(2594): note: the template instantiation context (the oldest one first) is
C:\Users\hp\source\repos\variant-lite\test\variant.t.cpp(1347): note: see reference to function template instantiation 'lest::result lest::expression_lhs<const nonstd::variants::variant<int,char,nonstd::variants::detail::T2,nonstd::variants::detail::T3,nonstd::variants::detail::T4,nonstd::variants::detail::T5,nonstd::variants::detail::T6,nonstd::variants::detail::T7,nonstd::variants::detail::T8,nonstd::variants::detail::T9,nonstd::variants::detail::T10,nonstd::variants::detail::T11,nonstd::variants::detail::T12,nonstd::variants::detail::T13,nonstd::variants::detail::T14,nonstd::variants::detail::T15> &>::operator ==<nonstd::variants::variant<int,char,nonstd::variants::detail::T2,nonstd::variants::detail::T3,nonstd::variants::detail::T4,nonstd::variants::detail::T5,nonstd::variants::detail::T6,nonstd::variants::detail::T7,nonstd::variants::detail::T8,nonstd::variants::detail::T9,nonstd::variants::detail::T10,nonstd::variants::detail::T11,nonstd::variants::detail::T12,nonstd::variants::detail::T13,nonstd::variants::detail::T14,nonstd::variants::detail::T15>>(const R &)' being compiled
        with
        [
            R=nonstd::variants::variant<int,char,nonstd::variants::detail::T2,nonstd::variants::detail::T3,nonstd::variants::detail::T4,nonstd::variants::detail::T5,nonstd::variants::detail::T6,nonstd::variants::detail::T7,nonstd::variants::detail::T8,nonstd::variants::detail::T9,nonstd::variants::detail::T10,nonstd::variants::detail::T11,nonstd::variants::detail::T12,nonstd::variants::detail::T13,nonstd::variants::detail::T14,nonstd::variants::detail::T15>
        ]
C:\Users\hp\source\repos\variant-lite\test\variant.t.cpp(1347): note: see the first reference to 'lest::expression_lhs<const nonstd::variants::variant<int,char,nonstd::variants::detail::T2,nonstd::variants::detail::T3,nonstd::variants::detail::T4,nonstd::variants::detail::T5,nonstd::variants::detail::T6,nonstd::variants::detail::T7,nonstd::variants::detail::T8,nonstd::variants::detail::T9,nonstd::variants::detail::T10,nonstd::variants::detail::T11,nonstd::variants::detail::T12,nonstd::variants::detail::T13,nonstd::variants::detail::T14,nonstd::variants::detail::T15> &>::operator ==' in '__lest_function__1343'
C:\Users\hp\source\repos\variant-lite\test\lest\lest_cpp03.hpp(770): note: see reference to function template instantiation 'bool nonstd::variants::operator ==<int,char,nonstd::variants::detail::T2,nonstd::variants::detail::T3,nonstd::variants::detail::T4,nonstd::variants::detail::T5,nonstd::variants::detail::T6,nonstd::variants::detail::T7,nonstd::variants::detail::T8,nonstd::variants::detail::T9,nonstd::variants::detail::T10,nonstd::variants::detail::T11,nonstd::variants::detail::T12,nonstd::variants::detail::T13,nonstd::variants::detail::T14,nonstd::variants::detail::T15>(const nonstd::variants::variant<int,char,nonstd::variants::detail::T2,nonstd::variants::detail::T3,nonstd::variants::detail::T4,nonstd::variants::detail::T5,nonstd::variants::detail::T6,nonstd::variants::detail::T7,nonstd::variants::detail::T8,nonstd::variants::detail::T9,nonstd::variants::detail::T10,nonstd::variants::detail::T11,nonstd::variants::detail::T12,nonstd::variants::detail::T13,nonstd::variants::detail::T14,nonstd::variants::detail::T15> &,const nonstd::variants::variant<int,char,nonstd::variants::detail::T2,nonstd::variants::detail::T3,nonstd::variants::detail::T4,nonstd::variants::detail::T5,nonstd::variants::detail::T6,nonstd::variants::detail::T7,nonstd::variants::detail::T8,nonstd::variants::detail::T9,nonstd::variants::detail::T10,nonstd::variants::detail::T11,nonstd::variants::detail::T12,nonstd::variants::detail::T13,nonstd::variants::detail::T14,nonstd::variants::detail::T15> &)' being compiled
C:\Users\hp\source\repos\variant-lite\include\nonstd/variant.hpp(2648): note: see reference to class template instantiation 'nonstd::variants::detail::Comparator<nonstd::variants::variant<int,char,nonstd::variants::detail::T2,nonstd::variants::detail::T3,nonstd::variants::detail::T4,nonstd::variants::detail::T5,nonstd::variants::detail::T6,nonstd::variants::detail::T7,nonstd::variants::detail::T8,nonstd::variants::detail::T9,nonstd::variants::detail::T10,nonstd::variants::detail::T11,nonstd::variants::detail::T12,nonstd::variants::detail::T13,nonstd::variants::detail::T14,nonstd::variants::detail::T15>>' being compiled
C:\Users\hp\source\repos\variant-lite\include\nonstd/variant.hpp(2588): note: while compiling class template member function 'bool nonstd::variants::detail::Comparator<nonstd::variants::variant<int,char,nonstd::variants::detail::T2,nonstd::variants::detail::T3,nonstd::variants::detail::T4,nonstd::variants::detail::T5,nonstd::variants::detail::T6,nonstd::variants::detail::T7,nonstd::variants::detail::T8,nonstd::variants::detail::T9,nonstd::variants::detail::T10,nonstd::variants::detail::T11,nonstd::variants::detail::T12,nonstd::variants::detail::T13,nonstd::variants::detail::T14,nonstd::variants::detail::T15>>::equal(const Variant &,const Variant &)'
        with
        [
            Variant=nonstd::variants::variant<int,char,nonstd::variants::detail::T2,nonstd::variants::detail::T3,nonstd::variants::detail::T4,nonstd::variants::detail::T5,nonstd::variants::detail::T6,nonstd::variants::detail::T7,nonstd::variants::detail::T8,nonstd::variants::detail::T9,nonstd::variants::detail::T10,nonstd::variants::detail::T11,nonstd::variants::detail::T12,nonstd::variants::detail::T13,nonstd::variants::detail::T14,nonstd::variants::detail::T15>
        ]
C:\Users\hp\source\repos\variant-lite\include\nonstd/variant.hpp(2648): note: see the first reference to 'nonstd::variants::detail::Comparator<nonstd::variants::variant<int,char,nonstd::variants::detail::T2,nonstd::variants::detail::T3,nonstd::variants::detail::T4,nonstd::variants::detail::T5,nonstd::variants::detail::T6,nonstd::variants::detail::T7,nonstd::variants::detail::T8,nonstd::variants::detail::T9,nonstd::variants::detail::T10,nonstd::variants::detail::T11,nonstd::variants::detail::T12,nonstd::variants::detail::T13,nonstd::variants::detail::T14,nonstd::variants::detail::T15>>::equal' in 'nonstd::variants::operator =='
C:\Users\hp\source\repos\variant-lite\test\lest\lest_cpp03.hpp(770): note: see the first reference to 'nonstd::variants::operator ==' in 'lest::expression_lhs<const nonstd::variants::variant<int,char,nonstd::variants::detail::T2,nonstd::variants::detail::T3,nonstd::variants::detail::T4,nonstd::variants::detail::T5,nonstd::variants::detail::T6,nonstd::variants::detail::T7,nonstd::variants::detail::T8,nonstd::variants::detail::T9,nonstd::variants::detail::T10,nonstd::variants::detail::T11,nonstd::variants::detail::T12,nonstd::variants::detail::T13,nonstd::variants::detail::T14,nonstd::variants::detail::T15> &>::operator =='
C:\Users\hp\source\repos\variant-lite\test\variant.t.cpp(1347): note: see the first reference to 'lest::expression_lhs<const nonstd::variants::variant<int,char,nonstd::variants::detail::T2,nonstd::variants::detail::T3,nonstd::variants::detail::T4,nonstd::variants::detail::T5,nonstd::variants::detail::T6,nonstd::variants::detail::T7,nonstd::variants::detail::T8,nonstd::variants::detail::T9,nonstd::variants::detail::T10,nonstd::variants::detail::T11,nonstd::variants::detail::T12,nonstd::variants::detail::T13,nonstd::variants::detail::T14,nonstd::variants::detail::T15> &>::operator ==' in '__lest_function__1343'
C:\Users\hp\source\repos\variant-lite\include\nonstd/variant.hpp(2595): error C2666: 'nonstd::variants::detail::TX<nonstd::variants::detail::S3>::operator ==': overloaded functions have similar conversions
C:\Users\hp\source\repos\variant-lite\include\nonstd/variant.hpp(667): note: could be 'bool nonstd::variants::detail::TX<nonstd::variants::detail::S3>::operator ==(const T &) const'
        with
        [
            T=nonstd::variants::detail::S3
        ]
C:\Users\hp\source\repos\variant-lite\include\nonstd/variant.hpp(667): note: or 'bool nonstd::variants::detail::TX<nonstd::variants::detail::S3>::operator ==(const T &) const' [synthesized expression 'y == x']
        with
        [
            T=nonstd::variants::detail::S3
        ]
C:\Users\hp\source\repos\variant-lite\include\nonstd/variant.hpp(2595): note: while trying to match the argument list '(const nonstd::variants::detail::TX<nonstd::variants::detail::S3>, const nonstd::variants::detail::TX<nonstd::variants::detail::S3>)'
C:\Users\hp\source\repos\variant-lite\include\nonstd/variant.hpp(2596): error C2666: 'nonstd::variants::detail::TX<nonstd::variants::detail::S4>::operator ==': overloaded functions have similar conversions
C:\Users\hp\source\repos\variant-lite\include\nonstd/variant.hpp(667): note: could be 'bool nonstd::variants::detail::TX<nonstd::variants::detail::S4>::operator ==(const T &) const'
        with
        [
            T=nonstd::variants::detail::S4
        ]
C:\Users\hp\source\repos\variant-lite\include\nonstd/variant.hpp(667): note: or 'bool nonstd::variants::detail::TX<nonstd::variants::detail::S4>::operator ==(const T &) const' [synthesized expression 'y == x']
        with
        [
            T=nonstd::variants::detail::S4
        ]
C:\Users\hp\source\repos\variant-lite\include\nonstd/variant.hpp(2596): note: while trying to match the argument list '(const nonstd::variants::detail::TX<nonstd::variants::detail::S4>, const nonstd::variants::detail::TX<nonstd::variants::detail::S4>)'
C:\Users\hp\source\repos\variant-lite\include\nonstd/variant.hpp(2597): error C2666: 'nonstd::variants::detail::TX<nonstd::variants::detail::S5>::operator ==': overloaded functions have similar conversions
C:\Users\hp\source\repos\variant-lite\include\nonstd/variant.hpp(667): note: could be 'bool nonstd::variants::detail::TX<nonstd::variants::detail::S5>::operator ==(const T &) const'
        with
        [
            T=nonstd::variants::detail::S5
        ]
C:\Users\hp\source\repos\variant-lite\include\nonstd/variant.hpp(667): note: or 'bool nonstd::variants::detail::TX<nonstd::variants::detail::S5>::operator ==(const T &) const' [synthesized expression 'y == x']
        with
        [
            T=nonstd::variants::detail::S5
        ]
C:\Users\hp\source\repos\variant-lite\include\nonstd/variant.hpp(2597): note: while trying to match the argument list '(const nonstd::variants::detail::TX<nonstd::variants::detail::S5>, const nonstd::variants::detail::TX<nonstd::variants::detail::S5>)'
C:\Users\hp\source\repos\variant-lite\include\nonstd/variant.hpp(2598): error C2666: 'nonstd::variants::detail::TX<nonstd::variants::detail::S6>::operator ==': overloaded functions have similar conversions
C:\Users\hp\source\repos\variant-lite\include\nonstd/variant.hpp(667): note: could be 'bool nonstd::variants::detail::TX<nonstd::variants::detail::S6>::operator ==(const T &) const'
        with
        [
            T=nonstd::variants::detail::S6
        ]
C:\Users\hp\source\repos\variant-lite\include\nonstd/variant.hpp(667): note: or 'bool nonstd::variants::detail::TX<nonstd::variants::detail::S6>::operator ==(const T &) const' [synthesized expression 'y == x']
        with
        [
            T=nonstd::variants::detail::S6
        ]
C:\Users\hp\source\repos\variant-lite\include\nonstd/variant.hpp(2598): note: while trying to match the argument list '(const nonstd::variants::detail::TX<nonstd::variants::detail::S6>, const nonstd::variants::detail::TX<nonstd::variants::detail::S6>)'
C:\Users\hp\source\repos\variant-lite\include\nonstd/variant.hpp(2599): error C2666: 'nonstd::variants::detail::TX<nonstd::variants::detail::S7>::operator ==': overloaded functions have similar conversions
C:\Users\hp\source\repos\variant-lite\include\nonstd/variant.hpp(667): note: could be 'bool nonstd::variants::detail::TX<nonstd::variants::detail::S7>::operator ==(const T &) const'
        with
        [
            T=nonstd::variants::detail::S7
        ]
C:\Users\hp\source\repos\variant-lite\include\nonstd/variant.hpp(667): note: or 'bool nonstd::variants::detail::TX<nonstd::variants::detail::S7>::operator ==(const T &) const' [synthesized expression 'y == x']
        with
        [
            T=nonstd::variants::detail::S7
        ]
C:\Users\hp\source\repos\variant-lite\include\nonstd/variant.hpp(2599): note: while trying to match the argument list '(const nonstd::variants::detail::TX<nonstd::variants::detail::S7>, const nonstd::variants::detail::TX<nonstd::variants::detail::S7>)'
C:\Users\hp\source\repos\variant-lite\include\nonstd/variant.hpp(2600): error C2666: 'nonstd::variants::detail::TX<nonstd::variants::detail::S8>::operator ==': overloaded functions have similar conversions
C:\Users\hp\source\repos\variant-lite\include\nonstd/variant.hpp(667): note: could be 'bool nonstd::variants::detail::TX<nonstd::variants::detail::S8>::operator ==(const T &) const'
        with
        [
            T=nonstd::variants::detail::S8
        ]
C:\Users\hp\source\repos\variant-lite\include\nonstd/variant.hpp(667): note: or 'bool nonstd::variants::detail::TX<nonstd::variants::detail::S8>::operator ==(const T &) const' [synthesized expression 'y == x']
        with
        [
            T=nonstd::variants::detail::S8
        ]
C:\Users\hp\source\repos\variant-lite\include\nonstd/variant.hpp(2600): note: while trying to match the argument list '(const nonstd::variants::detail::TX<nonstd::variants::detail::S8>, const nonstd::variants::detail::TX<nonstd::variants::detail::S8>)'
C:\Users\hp\source\repos\variant-lite\include\nonstd/variant.hpp(2601): error C2666: 'nonstd::variants::detail::TX<nonstd::variants::detail::S9>::operator ==': overloaded functions have similar conversions
C:\Users\hp\source\repos\variant-lite\include\nonstd/variant.hpp(667): note: could be 'bool nonstd::variants::detail::TX<nonstd::variants::detail::S9>::operator ==(const T &) const'
        with
        [
            T=nonstd::variants::detail::S9
        ]
C:\Users\hp\source\repos\variant-lite\include\nonstd/variant.hpp(667): note: or 'bool nonstd::variants::detail::TX<nonstd::variants::detail::S9>::operator ==(const T &) const' [synthesized expression 'y == x']
        with
        [
            T=nonstd::variants::detail::S9
        ]
C:\Users\hp\source\repos\variant-lite\include\nonstd/variant.hpp(2601): note: while trying to match the argument list '(const nonstd::variants::detail::TX<nonstd::variants::detail::S9>, const nonstd::variants::detail::TX<nonstd::variants::detail::S9>)'
C:\Users\hp\source\repos\variant-lite\include\nonstd/variant.hpp(2602): error C2666: 'nonstd::variants::detail::TX<nonstd::variants::detail::S10>::operator ==': overloaded functions have similar conversions
C:\Users\hp\source\repos\variant-lite\include\nonstd/variant.hpp(667): note: could be 'bool nonstd::variants::detail::TX<nonstd::variants::detail::S10>::operator ==(const T &) const'
        with
        [
            T=nonstd::variants::detail::S10
        ]
C:\Users\hp\source\repos\variant-lite\include\nonstd/variant.hpp(667): note: or 'bool nonstd::variants::detail::TX<nonstd::variants::detail::S10>::operator ==(const T &) const' [synthesized expression 'y == x']
        with
        [
            T=nonstd::variants::detail::S10
        ]
C:\Users\hp\source\repos\variant-lite\include\nonstd/variant.hpp(2602): note: while trying to match the argument list '(const nonstd::variants::detail::TX<nonstd::variants::detail::S10>, const nonstd::variants::detail::TX<nonstd::variants::detail::S10>)'
C:\Users\hp\source\repos\variant-lite\include\nonstd/variant.hpp(2603): error C2666: 'nonstd::variants::detail::TX<nonstd::variants::detail::S11>::operator ==': overloaded functions have similar conversions
C:\Users\hp\source\repos\variant-lite\include\nonstd/variant.hpp(667): note: could be 'bool nonstd::variants::detail::TX<nonstd::variants::detail::S11>::operator ==(const T &) const'
        with
        [
            T=nonstd::variants::detail::S11
        ]
C:\Users\hp\source\repos\variant-lite\include\nonstd/variant.hpp(667): note: or 'bool nonstd::variants::detail::TX<nonstd::variants::detail::S11>::operator ==(const T &) const' [synthesized expression 'y == x']
        with
        [
            T=nonstd::variants::detail::S11
        ]
C:\Users\hp\source\repos\variant-lite\include\nonstd/variant.hpp(2603): note: while trying to match the argument list '(const nonstd::variants::detail::TX<nonstd::variants::detail::S11>, const nonstd::variants::detail::TX<nonstd::variants::detail::S11>)'
C:\Users\hp\source\repos\variant-lite\include\nonstd/variant.hpp(2604): error C2666: 'nonstd::variants::detail::TX<nonstd::variants::detail::S12>::operator ==': overloaded functions have similar conversions
C:\Users\hp\source\repos\variant-lite\include\nonstd/variant.hpp(667): note: could be 'bool nonstd::variants::detail::TX<nonstd::variants::detail::S12>::operator ==(const T &) const'
        with
        [
            T=nonstd::variants::detail::S12
        ]
C:\Users\hp\source\repos\variant-lite\include\nonstd/variant.hpp(667): note: or 'bool nonstd::variants::detail::TX<nonstd::variants::detail::S12>::operator ==(const T &) const' [synthesized expression 'y == x']
        with
        [
            T=nonstd::variants::detail::S12
        ]
C:\Users\hp\source\repos\variant-lite\include\nonstd/variant.hpp(2604): note: while trying to match the argument list '(const nonstd::variants::detail::TX<nonstd::variants::detail::S12>, const nonstd::variants::detail::TX<nonstd::variants::detail::S12>)'
C:\Users\hp\source\repos\variant-lite\include\nonstd/variant.hpp(2605): error C2666: 'nonstd::variants::detail::TX<nonstd::variants::detail::S13>::operator ==': overloaded functions have similar conversions
C:\Users\hp\source\repos\variant-lite\include\nonstd/variant.hpp(667): note: could be 'bool nonstd::variants::detail::TX<nonstd::variants::detail::S13>::operator ==(const T &) const'
        with
        [
            T=nonstd::variants::detail::S13
        ]
C:\Users\hp\source\repos\variant-lite\include\nonstd/variant.hpp(667): note: or 'bool nonstd::variants::detail::TX<nonstd::variants::detail::S13>::operator ==(const T &) const' [synthesized expression 'y == x']
        with
        [
            T=nonstd::variants::detail::S13
        ]
C:\Users\hp\source\repos\variant-lite\include\nonstd/variant.hpp(2605): note: while trying to match the argument list '(const nonstd::variants::detail::TX<nonstd::variants::detail::S13>, const nonstd::variants::detail::TX<nonstd::variants::detail::S13>)'
C:\Users\hp\source\repos\variant-lite\include\nonstd/variant.hpp(2606): error C2666: 'nonstd::variants::detail::TX<nonstd::variants::detail::S14>::operator ==': overloaded functions have similar conversions
C:\Users\hp\source\repos\variant-lite\include\nonstd/variant.hpp(667): note: could be 'bool nonstd::variants::detail::TX<nonstd::variants::detail::S14>::operator ==(const T &) const'
        with
        [
            T=nonstd::variants::detail::S14
        ]
C:\Users\hp\source\repos\variant-lite\include\nonstd/variant.hpp(667): note: or 'bool nonstd::variants::detail::TX<nonstd::variants::detail::S14>::operator ==(const T &) const' [synthesized expression 'y == x']
        with
        [
            T=nonstd::variants::detail::S14
        ]
C:\Users\hp\source\repos\variant-lite\include\nonstd/variant.hpp(2606): note: while trying to match the argument list '(const nonstd::variants::detail::TX<nonstd::variants::detail::S14>, const nonstd::variants::detail::TX<nonstd::variants::detail::S14>)'
C:\Users\hp\source\repos\variant-lite\include\nonstd/variant.hpp(2607): error C2666: 'nonstd::variants::detail::TX<nonstd::variants::detail::S15>::operator ==': overloaded functions have similar conversions
C:\Users\hp\source\repos\variant-lite\include\nonstd/variant.hpp(667): note: could be 'bool nonstd::variants::detail::TX<nonstd::variants::detail::S15>::operator ==(const T &) const'
        with
        [
            T=nonstd::variants::detail::S15
        ]
C:\Users\hp\source\repos\variant-lite\include\nonstd/variant.hpp(667): note: or 'bool nonstd::variants::detail::TX<nonstd::variants::detail::S15>::operator ==(const T &) const' [synthesized expression 'y == x']
        with
        [
            T=nonstd::variants::detail::S15
        ]
C:\Users\hp\source\repos\variant-lite\include\nonstd/variant.hpp(2607): note: while trying to match the argument list '(const nonstd::variants::detail::TX<nonstd::variants::detail::S15>, const nonstd::variants::detail::TX<nonstd::variants::detail::S15>)'
[6/8 0.6/sec] Building CXX object test\CMakeFiles\variant-lite-cpp17.t.dir\variant.t.cpp.obj

If someone is already working on fixing this CI/CD issue then maybe i can help them since i can replicate the issue on my machine.

@martinmoene
Copy link
Collaborator

martinmoene commented Sep 23, 2025

You're right.

Apparently I've been working on it without finishing.

Locally I have changes adding explicit, like:

explicit variant( T0 const & t0 ) : type_index( 0 ) { new( ptr() ) T0( t0 ); }
...

It has been a long time since actively working on the -lite projects.

Another thing that resurfaced (issue #54, PR #55), is that nonstd/variant.hpp is/must be generated from template/variant.hpp via script/generate_header.py, so changes must go into template/variant.hpp . It seems I have to get the script working again... Also, it appears that the last change has not updated the variant template file first.

So the first thing I'm going to do is to correct this and create a sound base to work from.

@martinmoene
Copy link
Collaborator

martinmoene commented Sep 24, 2025

My proofing sofar:

// main.cpp
// mix C++17 std::monostate and std::bad_variant_access with nonstd::variant with configurable such types.

#define variant_CONFIG_SELECT_VARIANT       variant_VARIANT_NONSTD 
#define variant_CONFIG_MONOSTATE            std::monostate
#define variant_CONFIG_BAD_VARIANT_ACCESS   std::bad_variant_access

#include <iostream>
#include <string>
#include <utility>      // std::monostate
#include <optional>
#include <variant>
#include "nonstd/variant.hpp"

namespace std_compat
{
    using std::monostate;
    using std::bad_variant_access;
}

namespace std_compat
{
    template <class T>
    using optional = std::optional<T>;

    using std::bad_optional_access;
    using std::in_place_t;
    using std::in_place;
    using std::nullopt;
    using std::nullopt_t;
    using std::make_optional;
    using std::swap;
}

namespace std_compat
{
    template <class... Types>
    using variant = nonstd::variant<Types...>;

    // using nonstd::bad_variant_access;
    // using nonstd::monostate;
    using nonstd::in_place_type_t;
    using nonstd::in_place_type;
    using nonstd::in_place_index_t;
    using nonstd::in_place_index;
    using nonstd::get;
    using nonstd::get_if;
    using nonstd::holds_alternative;
    using nonstd::visit;
    using nonstd::variant_npos;
    using nonstd::variant_size;
    using nonstd::variant_size_v;
    using nonstd::variant_alternative;
    using nonstd::variant_alternative_t;
}

int main()
{
    // using namespace std_compat;
    // use namespace std_compat explicitly, as to avoid 'invisible' parameter type-dependent (Koenig) lookup

    auto opt = std_compat::optional<std::string>(std_compat::in_place, std::string("std::optional") );

    auto var = std_compat::variant<int, std::string>(std_compat::in_place_type<std::string>, std::string("std::optional") );

    try
    {
        auto result = std_compat::get<int>(var);
    } 
    catch( std_compat::bad_variant_access const & e ) 
    {
        std::cout << "std_compat::bad_variant_access: '" << e.what() << "'";
    }
}

// cl -nologo -EHsc -std:c++17 -I../../variant-lite/include main.cpp && main.exe
// g++ -std=c++17 -Wall -I../../variant-lite/include main.cpp -o main.exe && main.exe

#ifdef MSVC_OUTPUT
CMD> cl -nologo -EHsc -std:c++17 -I../../variant-lite/include -Dvariant_CONFIG_SELECT_VARIANT=variant_VARIANT_NONSTD main.cpp && main.exe
main.cpp
../../variant-lite/include\nonstd/variant.hpp(2723): error C2766: explicit specialization; 'std::hash<std::monostate>' has already been defined
C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.44.35207\include\variant(1706): note: see previous definition of 'std::hash<std::monostate>'
#endif

#ifdef GCC_OUTPUT
CMD> g++ -std=c++17 -Wall -I../../variant-lite/include main.cpp -o main.exe && main.exe
In file included from main.cpp:12:
../../variant-lite/include/nonstd/variant.hpp:2723:8: error: redefinition of 'struct std::hash<std::monostate>'
 2723 | struct hash< nonstd::monostate >
      |        ^~~~~~~~~~~~~~~~~~~~~~~~~
In file included from main.cpp:11:
c:\mingw\include\c++\11.2.0\variant:1829:12: note: previous definition of 'struct std::hash<std::monostate>'
 1829 |     struct hash<monostate>
      |            ^~~~~~~~~~~~~~~
main.cpp: In function 'int main()':
main.cpp:67:14: warning: unused variable 'result' [-Wunused-variable]
   67 |         auto result = std_compat::get<int>(var);
      |              ^~~~~~
#endif

@martinmoene martinmoene merged commit da9b8ca into nonstd-lite:master Sep 25, 2025
6 of 7 checks passed
@martinmoene
Copy link
Collaborator

@MostafaNanticock , Thanks for your contribution & efforts.

@MostafaNanticock
Copy link
Contributor Author

@martinmoene
don''t you think it would be a good idea to add this test case to the other unit tests?

// main.cpp
// mix C++17 std::monostate and std::bad_variant_access with nonstd::variant with configurable such types.

#define variant_CONFIG_SELECT_VARIANT       variant_VARIANT_NONSTD 
#define variant_CONFIG_MONOSTATE            std::monostate
#define variant_CONFIG_BAD_VARIANT_ACCESS   std::bad_variant_access

#include <iostream>
#include <string>
#include <utility>      // std::monostate
#include <optional>
#include <variant>
#include "nonstd/variant.hpp"

namespace std_compat
{
    using std::monostate;
    using std::bad_variant_access;
}

namespace std_compat
{
    template <class T>
    using optional = std::optional<T>;

    using std::bad_optional_access;
    using std::in_place_t;
    using std::in_place;
    using std::nullopt;
    using std::nullopt_t;
    using std::make_optional;
    using std::swap;
}

namespace std_compat
{
    template <class... Types>
    using variant = nonstd::variant<Types...>;

    // using nonstd::bad_variant_access;
    // using nonstd::monostate;
    using nonstd::in_place_type_t;
    using nonstd::in_place_type;
    using nonstd::in_place_index_t;
    using nonstd::in_place_index;
    using nonstd::get;
    using nonstd::get_if;
    using nonstd::holds_alternative;
    using nonstd::visit;
    using nonstd::variant_npos;
    using nonstd::variant_size;
    using nonstd::variant_size_v;
    using nonstd::variant_alternative;
    using nonstd::variant_alternative_t;
}

int main()
{
    // using namespace std_compat;
    // use namespace std_compat explicitly, as to avoid 'invisible' parameter type-dependent (Koenig) lookup

    auto opt = std_compat::optional<std::string>(std_compat::in_place, std::string("std::optional") );

    auto var = std_compat::variant<int, std::string>(std_compat::in_place_type<std::string>, std::string("std::optional") );

    try
    {
        auto result = std_compat::get<int>(var);
    } 
    catch( std_compat::bad_variant_access const & e ) 
    {
        std::cout << "std_compat::bad_variant_access: '" << e.what() << "'";
    }
}

I can do that if you want

@martinmoene
Copy link
Collaborator

@MostafaNanticock , It is indeed, thanks for mentioning it.

I'll do that later today.

@martinmoene
Copy link
Collaborator

@MostafaNanticock , the error you bring-up in this remark above for msvc 2022/17 using cl -std:c++latest has been fixed in commit f1512d5.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants