I have currently this:
template<TagType TTag, IsTag ...Tags>
struct RequiredTagList
{
static constexpr const TagType index = TTag;
};
// ---------------------------------------------------------------
using fix::TagType = uint16_t;
template<fix::TagType Tag, IsTagList ...Ts>
struct Select_Tag_List;
template<fix::TagType Tag, IsTagList TagList, IsTagList ...TagLists>
struct Select_Tag_List<Tag, TagList, TagLists...>
{
static constexpr const fix::TagType tag_index = TagList::index;
using type = std::conditional_t<tag_index == Tag,
TagList,
typename Select_Tag_List<Tag, TagLists...>::type
>;
};
template<fix::TagType Tag>
struct Select_Tag_List<Tag>
{
static_assert(std::same_as<void,int>, "Tag not found, see template build stack");
};
template<fix::TagType Tag, IsTagList ...Ts>
using select_tag_list = Select_Tag_List<Tag, Ts...>;
template<fix::TagType Tag, IsTagList ...Ts>
using select_tag_list_t = typename Select_Tag_List<Tag, Ts...>::type;
The concept IsTagList
validate that T
is a Required<TTag, Tags...>
and have member static property T::index
(fix::TagType
)
But when I call it using this template parameter:
Select_Tag_List<268,fix::RequiredTagList<268,fix::Required<269>,fix::Required<270>,fix::Optional<271>>>
The list of template argument fix::Required<269>,fix::Required<270>,fix::Optional<271>
validate the IsTag
concept, but are not relevant to the issue (it could be any type/concept)
I would have assumed that std::conditional_t
will not evaluate the specialization of Select_Tag_List<Tag>
, but the static_assert is still trigger.
I'm using MSVC and I saw that it evaluate both the true and false result type even when not necessary, so I tried to replace std::conditional_t
by this implementation, to force the non evaluation of the false value if the result is true:
template <bool Condition, typename Then, typename Else>
struct Lazy_Conditional;
template <typename Then, typename Else>
struct Lazy_Conditional<true, Then, Else>
{
using type = Then;
};
template <typename Then, typename Else>
struct Lazy_Conditional<false, Then, Else>
{
using type = Else;
};
template <bool Condition, typename Then, typename Else>
using lazy_conditional = Lazy_Conditional<Condition, Then, Else>;
template <bool Condition, typename Then, typename Else>
using lazy_conditional_t = typename lazy_conditional<Condition, Then, Else>::type;
But without success and still ending update with error C2039: 'type': is not a member of 'meta::Select_Tag_List<268>'
and Tag not found, see template build stack
Do you have any idea on how can I make my condition not evaluate the false type if the condition result is true?
As @tkausl mention in a comment the ::type
in the false result branch force it's evaluation:
typename Select_Tag_List<Tag, TagsList...>::type
To fix the issue I added a wrapper around the true branch as:
using type = typename lazy_conditional_t<tag_index == Tag,
std::type_identity<TagList>,
Select_Tag_List<Tag, TagLists...>
>::type;