Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Does Boost Variant provides a similar function as std's holds_alternative?

Tags:

c++

boost

I found this code on cppreference.com. I was wondering if boost provides a similar function for its variant type. I found the boost documentation really awful and can't find anything.

int main()
{
    std::variant<int, std::string> v = "abc";
    std::cout << std::boolalpha
              << "variant holds int? "
              << std::holds_alternative<int>(v) << '\n'
              << "variant holds string? "
              << std::holds_alternative<std::string>(v) << '\n';
}
like image 958
linSESH Avatar asked Aug 09 '18 10:08

linSESH


3 Answers

You can create a simple wrapper that will work just like the standard one. Use the fact that boost::get has multiple overloads and when passed a pointer, it will also return a (possibly null) pointer.

template <typename T, typename... Ts>
bool holds_alternative(const boost::variant<Ts...>& v) noexcept
{
    return boost::get<T>(&v) != nullptr;
}

It will be also picked up by ADL, so it doesn't matter much where you put it.

like image 95
Xeverous Avatar answered Oct 07 '22 01:10

Xeverous


Although not exactly the same, you can use the pointer based get function:

boost::variant<int, std::string> v = "abc";

std::cout << std::boolalpha
          << "variant holds int? "
          << (boost::get<int>(&v) != nullptr) << '\n'
          << "variant holds string? "
          << (boost::get<std::string>(&v) != nullptr) << '\n';
like image 7
lubgr Avatar answered Oct 06 '22 23:10

lubgr


No but, you can use the type() method:

#include <iostream>
#include <boost/variant.hpp>

int main()
{
    boost::variant<int, std::string> v = "abc";
    std::cout << std::boolalpha
              << "variant holds int? "
              << (v.type() == typeid(int)) << '\n'
              << "variant holds string? "
              << (v.type() == typeid(std::string)) << '\n';
}

But it will not protect you against having the same type twice (boost::variant<int, int, std::string>) as std::holds_alternative would do.

like image 5
Tobi Avatar answered Oct 06 '22 23:10

Tobi