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;
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
add a comment |
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
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 isif constexpr (std::is_convertible_v<Gamma, CustomVariant>).
– Raymond Chen
Mar 26 at 0:53
add a comment |
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
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
c++ c++11 templates variant
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 isif constexpr (std::is_convertible_v<Gamma, CustomVariant>).
– Raymond Chen
Mar 26 at 0:53
add a comment |
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 isif 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
add a comment |
2 Answers
2
active
oldest
votes
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
add a comment |
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.
add a comment |
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
);
);
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
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
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
add a comment |
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
add a comment |
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
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
answered Mar 26 at 1:12
xaxxonxaxxon
15.2k4 gold badges33 silver badges63 bronze badges
15.2k4 gold badges33 silver badges63 bronze badges
add a comment |
add a comment |
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.
add a comment |
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.
add a comment |
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.
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.
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
add a comment |
add a comment |
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.
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
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
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
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
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