Get type from variant at compile timeWhat are POD types in C++?Do the parentheses after the type name make a difference with new?Why is reading lines from stdin much slower in C++ than Python?Compiling C++11 with g++boost::variant can not handle string and wstring togetherFunction template parameterCompiling an application for use in highly radioactive environmentsHow to specialize templated class methods based on type traits? Using std::enable_if works for non-class functions, but fails for class methodsSimple template class member function specialization that returns a valueWhy did this error occur? c++ library build

Could you brine steak?

In Spider-Man: Far From Home, is this superhero name a reference to another comic book?

Stacked light circle effect in Photoshop?

How many tone holes are there actually in different orchestral woodwind instruments?

Why is the ladder of the LM always in the dark side of the LM?

Why did Harry Potter get a bedroom?

Chorophyll and photosynthesis in plants with coloured leaves

What is the minimum time required for final wash in film development?

When I press the space bar it deletes the letters in front of it

What is a "Lear Processor" and how did it work?

Is there any reason why MCU changed the Snap to Blip

Were Pandaria, Broken Isles, Northrend, Kul'Tiras and Zandalar also affected by the Cataclysm?

Data Encryption by Application vs Data Encryption in Database

Is it okay to use open source code to do an interview task?

Reverse dots and boxes

What are similar black and/or white permanents to Divine Visitation?

Party going through airport security at separate times?

LED glows slightly during soldering

What is /bin/red

What's it called when the bad guy gets eaten?

Is that a case of "DOUBLE-NEGATIVES" as claimed by Grammarly?

Why different specifications for telescopes and binoculars?

What would +1/+2/+3 items be called in game?

Having decision making power over someone's assets



Get type from variant at compile time


What are POD types in C++?Do the parentheses after the type name make a difference with new?Why is reading lines from stdin much slower in C++ than Python?Compiling C++11 with g++boost::variant can not handle string and wstring togetherFunction template parameterCompiling an application for use in highly radioactive environmentsHow to specialize templated class methods based on type traits? Using std::enable_if works for non-class functions, but fails for class methodsSimple template class member function specialization that returns a valueWhy did this error occur? c++ library build






.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty margin-bottom:0;








0















I need to do a typecheck on whether a variant type can hold a type at compile time.



I am converting an enum and a string to a variant, but I want the library to be compatible with a user provided variant (for the types they support). So I have a template parameter CustomVariant to represent a variant over a subset of the supported types, AlphaBeta, Gamma, Delta, and Epsilon. I would like to return std::nullopt if I can't create a valid variant.



template <typename CustomVariant>
std::optional<CustomVariant> AsCustomVariant(LargeEnum type, const std::string& name)
case LargeEnum::ALPHA:
case LargeEnum::BETA:
return ConvertAlphaBeta(name);

case LargeEnum::GAMMA:
return ConvertGamma(name);

case LargeEnum::DELTA:
return ConvertDelta(name);

case LargeEnum::EPSILON:
return ConvertEpsilon(name);

default:
return std::nullopt;



The idea is to use some sort of template magic that can do something like:



if (std::type_can_convert<CustomVariant, Gamma>) 
return ConvertGamma(name);
else
return std::nullopt;










share|improve this question
























  • What is CustomVariant? Is it a std variant? Is Gamma a type? If tha variant hokds a type that can be converted-from the reyurn type of ConvertGamma, is that good enough, or only exact matches? If the first, what kind of ordering? Where is your switch statement, it appears to be missing. Is LargeEnum contiguous?

    – Yakk - Adam Nevraumont
    Mar 26 at 0:29







  • 2





    The template magic you're looking for is if constexpr (std::is_convertible_v<Gamma, CustomVariant>).

    – Raymond Chen
    Mar 26 at 0:53

















0















I need to do a typecheck on whether a variant type can hold a type at compile time.



I am converting an enum and a string to a variant, but I want the library to be compatible with a user provided variant (for the types they support). So I have a template parameter CustomVariant to represent a variant over a subset of the supported types, AlphaBeta, Gamma, Delta, and Epsilon. I would like to return std::nullopt if I can't create a valid variant.



template <typename CustomVariant>
std::optional<CustomVariant> AsCustomVariant(LargeEnum type, const std::string& name)
case LargeEnum::ALPHA:
case LargeEnum::BETA:
return ConvertAlphaBeta(name);

case LargeEnum::GAMMA:
return ConvertGamma(name);

case LargeEnum::DELTA:
return ConvertDelta(name);

case LargeEnum::EPSILON:
return ConvertEpsilon(name);

default:
return std::nullopt;



The idea is to use some sort of template magic that can do something like:



if (std::type_can_convert<CustomVariant, Gamma>) 
return ConvertGamma(name);
else
return std::nullopt;










share|improve this question
























  • What is CustomVariant? Is it a std variant? Is Gamma a type? If tha variant hokds a type that can be converted-from the reyurn type of ConvertGamma, is that good enough, or only exact matches? If the first, what kind of ordering? Where is your switch statement, it appears to be missing. Is LargeEnum contiguous?

    – Yakk - Adam Nevraumont
    Mar 26 at 0:29







  • 2





    The template magic you're looking for is if constexpr (std::is_convertible_v<Gamma, CustomVariant>).

    – Raymond Chen
    Mar 26 at 0:53













0












0








0








I need to do a typecheck on whether a variant type can hold a type at compile time.



I am converting an enum and a string to a variant, but I want the library to be compatible with a user provided variant (for the types they support). So I have a template parameter CustomVariant to represent a variant over a subset of the supported types, AlphaBeta, Gamma, Delta, and Epsilon. I would like to return std::nullopt if I can't create a valid variant.



template <typename CustomVariant>
std::optional<CustomVariant> AsCustomVariant(LargeEnum type, const std::string& name)
case LargeEnum::ALPHA:
case LargeEnum::BETA:
return ConvertAlphaBeta(name);

case LargeEnum::GAMMA:
return ConvertGamma(name);

case LargeEnum::DELTA:
return ConvertDelta(name);

case LargeEnum::EPSILON:
return ConvertEpsilon(name);

default:
return std::nullopt;



The idea is to use some sort of template magic that can do something like:



if (std::type_can_convert<CustomVariant, Gamma>) 
return ConvertGamma(name);
else
return std::nullopt;










share|improve this question
















I need to do a typecheck on whether a variant type can hold a type at compile time.



I am converting an enum and a string to a variant, but I want the library to be compatible with a user provided variant (for the types they support). So I have a template parameter CustomVariant to represent a variant over a subset of the supported types, AlphaBeta, Gamma, Delta, and Epsilon. I would like to return std::nullopt if I can't create a valid variant.



template <typename CustomVariant>
std::optional<CustomVariant> AsCustomVariant(LargeEnum type, const std::string& name)
case LargeEnum::ALPHA:
case LargeEnum::BETA:
return ConvertAlphaBeta(name);

case LargeEnum::GAMMA:
return ConvertGamma(name);

case LargeEnum::DELTA:
return ConvertDelta(name);

case LargeEnum::EPSILON:
return ConvertEpsilon(name);

default:
return std::nullopt;



The idea is to use some sort of template magic that can do something like:



if (std::type_can_convert<CustomVariant, Gamma>) 
return ConvertGamma(name);
else
return std::nullopt;







c++ c++11 templates variant






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Mar 26 at 17:34







Harrichael

















asked Mar 26 at 0:18









HarrichaelHarrichael

3052 silver badges8 bronze badges




3052 silver badges8 bronze badges












  • What is CustomVariant? Is it a std variant? Is Gamma a type? If tha variant hokds a type that can be converted-from the reyurn type of ConvertGamma, is that good enough, or only exact matches? If the first, what kind of ordering? Where is your switch statement, it appears to be missing. Is LargeEnum contiguous?

    – Yakk - Adam Nevraumont
    Mar 26 at 0:29







  • 2





    The template magic you're looking for is if constexpr (std::is_convertible_v<Gamma, CustomVariant>).

    – Raymond Chen
    Mar 26 at 0:53

















  • What is CustomVariant? Is it a std variant? Is Gamma a type? If tha variant hokds a type that can be converted-from the reyurn type of ConvertGamma, is that good enough, or only exact matches? If the first, what kind of ordering? Where is your switch statement, it appears to be missing. Is LargeEnum contiguous?

    – Yakk - Adam Nevraumont
    Mar 26 at 0:29







  • 2





    The template magic you're looking for is if constexpr (std::is_convertible_v<Gamma, CustomVariant>).

    – Raymond Chen
    Mar 26 at 0:53
















What is CustomVariant? Is it a std variant? Is Gamma a type? If tha variant hokds a type that can be converted-from the reyurn type of ConvertGamma, is that good enough, or only exact matches? If the first, what kind of ordering? Where is your switch statement, it appears to be missing. Is LargeEnum contiguous?

– Yakk - Adam Nevraumont
Mar 26 at 0:29






What is CustomVariant? Is it a std variant? Is Gamma a type? If tha variant hokds a type that can be converted-from the reyurn type of ConvertGamma, is that good enough, or only exact matches? If the first, what kind of ordering? Where is your switch statement, it appears to be missing. Is LargeEnum contiguous?

– Yakk - Adam Nevraumont
Mar 26 at 0:29





2




2





The template magic you're looking for is if constexpr (std::is_convertible_v<Gamma, CustomVariant>).

– Raymond Chen
Mar 26 at 0:53





The template magic you're looking for is if constexpr (std::is_convertible_v<Gamma, CustomVariant>).

– Raymond Chen
Mar 26 at 0:53












2 Answers
2






active

oldest

votes


















2














With c++17 (I know it's tagged with c++11), this is super easy - you don't even have to really do anything:



#include <variant>
#include <type_traits>
#include <string>

using namespace std;

int main()

// this works, as expected
if constexpr(is_constructible_v<variant<int>, double>)
// this will run


// this is fine - it just won't happen,
if constexpr(is_constructible_v<variant<int>, string>)
// this won't run
else
// this will run

// but obviously the assignment of a string into that variant doesn't work...
variant<int> vi="asdf"s;



https://godbolt.org/z/I-wJU1






share|improve this answer






























    1














    First I'd do this:



    template<class T>struct tag_tusing type=T;;
    template<class T>constexpr tag_t<T> tag;

    template<class...Ts>using one_tag_of=std::variant<tag_t<Ts>...>;

    using which_type=one_tag_of<AlphaBeta, Gamma, Delta /* etc */>;

    which_type GetType(LargeEnum e)
    switch (e)
    case LargeEnum::Alpha:
    case LargeEnum::Beta: return tag<AlphaBeta>;
    // etc




    Now we do this:



    template <typename CustomVariant>
    std::optional<CustomVariant> AsCustomVariant(LargeEnum type, const std::string& name)
    auto which = GetType(type);
    return std::visit( [&name](auto tag)->std::optional<CustomVariant>
    using type=typename decltype(tag)::type;
    if constexpr (std::is_convertible<CustomVariant, type>)
    return MakeFromString( tag, name );
    return std::nullopt;
    , which );



    this leaves MakeFromString.



    Write overloads like this:



    inline Delta MakeFromString(tag_t<Delta>, std::string const& name) return ConvertDelta(name); 


    note, not specializations. Just overloads.






    share|improve this answer



























      Your Answer






      StackExchange.ifUsing("editor", function ()
      StackExchange.using("externalEditor", function ()
      StackExchange.using("snippets", function ()
      StackExchange.snippets.init();
      );
      );
      , "code-snippets");

      StackExchange.ready(function()
      var channelOptions =
      tags: "".split(" "),
      id: "1"
      ;
      initTagRenderer("".split(" "), "".split(" "), channelOptions);

      StackExchange.using("externalEditor", function()
      // Have to fire editor after snippets, if snippets enabled
      if (StackExchange.settings.snippets.snippetsEnabled)
      StackExchange.using("snippets", function()
      createEditor();
      );

      else
      createEditor();

      );

      function createEditor()
      StackExchange.prepareEditor(
      heartbeatType: 'answer',
      autoActivateHeartbeat: false,
      convertImagesToLinks: true,
      noModals: true,
      showLowRepImageUploadWarning: true,
      reputationToPostImages: 10,
      bindNavPrevention: true,
      postfix: "",
      imageUploader:
      brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
      contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
      allowUrls: true
      ,
      onDemand: true,
      discardSelector: ".discard-answer"
      ,immediatelyShowMarkdownHelp:true
      );



      );













      draft saved

      draft discarded


















      StackExchange.ready(
      function ()
      StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f55348169%2fget-type-from-variant-at-compile-time%23new-answer', 'question_page');

      );

      Post as a guest















      Required, but never shown

























      2 Answers
      2






      active

      oldest

      votes








      2 Answers
      2






      active

      oldest

      votes









      active

      oldest

      votes






      active

      oldest

      votes









      2














      With c++17 (I know it's tagged with c++11), this is super easy - you don't even have to really do anything:



      #include <variant>
      #include <type_traits>
      #include <string>

      using namespace std;

      int main()

      // this works, as expected
      if constexpr(is_constructible_v<variant<int>, double>)
      // this will run


      // this is fine - it just won't happen,
      if constexpr(is_constructible_v<variant<int>, string>)
      // this won't run
      else
      // this will run

      // but obviously the assignment of a string into that variant doesn't work...
      variant<int> vi="asdf"s;



      https://godbolt.org/z/I-wJU1






      share|improve this answer



























        2














        With c++17 (I know it's tagged with c++11), this is super easy - you don't even have to really do anything:



        #include <variant>
        #include <type_traits>
        #include <string>

        using namespace std;

        int main()

        // this works, as expected
        if constexpr(is_constructible_v<variant<int>, double>)
        // this will run


        // this is fine - it just won't happen,
        if constexpr(is_constructible_v<variant<int>, string>)
        // this won't run
        else
        // this will run

        // but obviously the assignment of a string into that variant doesn't work...
        variant<int> vi="asdf"s;



        https://godbolt.org/z/I-wJU1






        share|improve this answer

























          2












          2








          2







          With c++17 (I know it's tagged with c++11), this is super easy - you don't even have to really do anything:



          #include <variant>
          #include <type_traits>
          #include <string>

          using namespace std;

          int main()

          // this works, as expected
          if constexpr(is_constructible_v<variant<int>, double>)
          // this will run


          // this is fine - it just won't happen,
          if constexpr(is_constructible_v<variant<int>, string>)
          // this won't run
          else
          // this will run

          // but obviously the assignment of a string into that variant doesn't work...
          variant<int> vi="asdf"s;



          https://godbolt.org/z/I-wJU1






          share|improve this answer













          With c++17 (I know it's tagged with c++11), this is super easy - you don't even have to really do anything:



          #include <variant>
          #include <type_traits>
          #include <string>

          using namespace std;

          int main()

          // this works, as expected
          if constexpr(is_constructible_v<variant<int>, double>)
          // this will run


          // this is fine - it just won't happen,
          if constexpr(is_constructible_v<variant<int>, string>)
          // this won't run
          else
          // this will run

          // but obviously the assignment of a string into that variant doesn't work...
          variant<int> vi="asdf"s;



          https://godbolt.org/z/I-wJU1







          share|improve this answer












          share|improve this answer



          share|improve this answer










          answered Mar 26 at 1:12









          xaxxonxaxxon

          15.2k4 gold badges33 silver badges63 bronze badges




          15.2k4 gold badges33 silver badges63 bronze badges























              1














              First I'd do this:



              template<class T>struct tag_tusing type=T;;
              template<class T>constexpr tag_t<T> tag;

              template<class...Ts>using one_tag_of=std::variant<tag_t<Ts>...>;

              using which_type=one_tag_of<AlphaBeta, Gamma, Delta /* etc */>;

              which_type GetType(LargeEnum e)
              switch (e)
              case LargeEnum::Alpha:
              case LargeEnum::Beta: return tag<AlphaBeta>;
              // etc




              Now we do this:



              template <typename CustomVariant>
              std::optional<CustomVariant> AsCustomVariant(LargeEnum type, const std::string& name)
              auto which = GetType(type);
              return std::visit( [&name](auto tag)->std::optional<CustomVariant>
              using type=typename decltype(tag)::type;
              if constexpr (std::is_convertible<CustomVariant, type>)
              return MakeFromString( tag, name );
              return std::nullopt;
              , which );



              this leaves MakeFromString.



              Write overloads like this:



              inline Delta MakeFromString(tag_t<Delta>, std::string const& name) return ConvertDelta(name); 


              note, not specializations. Just overloads.






              share|improve this answer





























                1














                First I'd do this:



                template<class T>struct tag_tusing type=T;;
                template<class T>constexpr tag_t<T> tag;

                template<class...Ts>using one_tag_of=std::variant<tag_t<Ts>...>;

                using which_type=one_tag_of<AlphaBeta, Gamma, Delta /* etc */>;

                which_type GetType(LargeEnum e)
                switch (e)
                case LargeEnum::Alpha:
                case LargeEnum::Beta: return tag<AlphaBeta>;
                // etc




                Now we do this:



                template <typename CustomVariant>
                std::optional<CustomVariant> AsCustomVariant(LargeEnum type, const std::string& name)
                auto which = GetType(type);
                return std::visit( [&name](auto tag)->std::optional<CustomVariant>
                using type=typename decltype(tag)::type;
                if constexpr (std::is_convertible<CustomVariant, type>)
                return MakeFromString( tag, name );
                return std::nullopt;
                , which );



                this leaves MakeFromString.



                Write overloads like this:



                inline Delta MakeFromString(tag_t<Delta>, std::string const& name) return ConvertDelta(name); 


                note, not specializations. Just overloads.






                share|improve this answer



























                  1












                  1








                  1







                  First I'd do this:



                  template<class T>struct tag_tusing type=T;;
                  template<class T>constexpr tag_t<T> tag;

                  template<class...Ts>using one_tag_of=std::variant<tag_t<Ts>...>;

                  using which_type=one_tag_of<AlphaBeta, Gamma, Delta /* etc */>;

                  which_type GetType(LargeEnum e)
                  switch (e)
                  case LargeEnum::Alpha:
                  case LargeEnum::Beta: return tag<AlphaBeta>;
                  // etc




                  Now we do this:



                  template <typename CustomVariant>
                  std::optional<CustomVariant> AsCustomVariant(LargeEnum type, const std::string& name)
                  auto which = GetType(type);
                  return std::visit( [&name](auto tag)->std::optional<CustomVariant>
                  using type=typename decltype(tag)::type;
                  if constexpr (std::is_convertible<CustomVariant, type>)
                  return MakeFromString( tag, name );
                  return std::nullopt;
                  , which );



                  this leaves MakeFromString.



                  Write overloads like this:



                  inline Delta MakeFromString(tag_t<Delta>, std::string const& name) return ConvertDelta(name); 


                  note, not specializations. Just overloads.






                  share|improve this answer















                  First I'd do this:



                  template<class T>struct tag_tusing type=T;;
                  template<class T>constexpr tag_t<T> tag;

                  template<class...Ts>using one_tag_of=std::variant<tag_t<Ts>...>;

                  using which_type=one_tag_of<AlphaBeta, Gamma, Delta /* etc */>;

                  which_type GetType(LargeEnum e)
                  switch (e)
                  case LargeEnum::Alpha:
                  case LargeEnum::Beta: return tag<AlphaBeta>;
                  // etc




                  Now we do this:



                  template <typename CustomVariant>
                  std::optional<CustomVariant> AsCustomVariant(LargeEnum type, const std::string& name)
                  auto which = GetType(type);
                  return std::visit( [&name](auto tag)->std::optional<CustomVariant>
                  using type=typename decltype(tag)::type;
                  if constexpr (std::is_convertible<CustomVariant, type>)
                  return MakeFromString( tag, name );
                  return std::nullopt;
                  , which );



                  this leaves MakeFromString.



                  Write overloads like this:



                  inline Delta MakeFromString(tag_t<Delta>, std::string const& name) return ConvertDelta(name); 


                  note, not specializations. Just overloads.







                  share|improve this answer














                  share|improve this answer



                  share|improve this answer








                  edited Mar 26 at 2:49

























                  answered Mar 26 at 0:43









                  Yakk - Adam NevraumontYakk - Adam Nevraumont

                  194k21 gold badges213 silver badges401 bronze badges




                  194k21 gold badges213 silver badges401 bronze badges



























                      draft saved

                      draft discarded
















































                      Thanks for contributing an answer to Stack Overflow!


                      • Please be sure to answer the question. Provide details and share your research!

                      But avoid


                      • Asking for help, clarification, or responding to other answers.

                      • Making statements based on opinion; back them up with references or personal experience.

                      To learn more, see our tips on writing great answers.




                      draft saved


                      draft discarded














                      StackExchange.ready(
                      function ()
                      StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f55348169%2fget-type-from-variant-at-compile-time%23new-answer', 'question_page');

                      );

                      Post as a guest















                      Required, but never shown





















































                      Required, but never shown














                      Required, but never shown












                      Required, but never shown







                      Required, but never shown

































                      Required, but never shown














                      Required, but never shown












                      Required, but never shown







                      Required, but never shown







                      Popular posts from this blog

                      SQL error code 1064 with creating Laravel foreign keysForeign key constraints: When to use ON UPDATE and ON DELETEDropping column with foreign key Laravel error: General error: 1025 Error on renameLaravel SQL Can't create tableLaravel Migration foreign key errorLaravel php artisan migrate:refresh giving a syntax errorSQLSTATE[42S01]: Base table or view already exists or Base table or view already exists: 1050 Tableerror in migrating laravel file to xampp serverSyntax error or access violation: 1064:syntax to use near 'unsigned not null, modelName varchar(191) not null, title varchar(191) not nLaravel cannot create new table field in mysqlLaravel 5.7:Last migration creates table but is not registered in the migration table

                      용인 삼성생명 블루밍스 목차 통계 역대 감독 선수단 응원단 경기장 같이 보기 외부 링크 둘러보기 메뉴samsungblueminx.comeh선수 명단용인 삼성생명 블루밍스용인 삼성생명 블루밍스ehsamsungblueminx.comeheheheh

                      155 수학 과학 기타 둘러보기 메뉴eh추가해eh문서를 완성해