1

In templates I can do:

struct Type_Which_std_cout_MayAccept {};

template <typename T>
struct AAA
{
    AAA(T t) { if constexpr (false) std::cout << t; }
};

int main()
{
    AAA{ Type_Which_std_cout_MayAccept() };
}

Which works fine. Which is why I why thought if the the constexpr condition is false the compiler won't try to evaluate the statement. So I expected this to work, but it doesn't. I obviously have the wrong understanding:

struct NoType {};


template <typename T>
struct MemberOrNothing
{
    MemberOrNothing(T arg) : member(arg) {}
    constexpr bool hasMember() { return true; }
    T member;
};
template <>
struct MemberOrNothing<NoType>
{
    MemberOrNothing(NoType) {}
    constexpr bool hasMember() { return false; }
};

template <typename T_MemberOne, typename T_OptionalSecondMember = NoType>
struct OneOrTwoMemberStruct
{
    OneOrTwoMemberStruct(T_MemberOne firstMember, T_OptionalSecondMember optionalSecond = NoType())
        : firstMember(firstMember), secondMember(optionalSecond)    {}


    T_MemberOne firstMember;
    MemberOrNothing<T_OptionalSecondMember> secondMember;
    T_OptionalSecondMember& getSecondMember() { return secondMember.member; }
    constexpr bool hasSecondMember() { return secondMember.hasMember(); }
    
};

int main()
{

      OneOrTwoMemberStruct objWithSecondMember{ 7, 'c' };
      OneOrTwoMemberStruct objWithoutSecondMember{ 7 };

    // Works
    if constexpr (objWithSecondMember.hasSecondMember())
        std::cout << objWithSecondMember.getSecondMember() << '\n';
    
    // Doesn't work, std::cout << doesn't accept a NoType
    if constexpr (false)
        std::cout << objWithoutSecondMember.getSecondMember() << '\n';
} 

In the first example I can write code that passes T to operator << of cout even if it doesn't accept a T, however in this this example I can't pass type that may or may not be accepted by cout operator << ?

Could someone explain the difference between the two?

Zebrafish
  • 11,682
  • 3
  • 43
  • 119
  • Does this answer your question? [How to assert that a constexpr if else clause never happen?](https://stackoverflow.com/questions/53945490/how-to-assert-that-a-constexpr-if-else-clause-never-happen) – mrks Dec 25 '20 at 16:53
  • tl;dr that trick only works for templates – Aykhan Hagverdili Dec 25 '20 at 16:54
  • The short answer is that in templates, the "false" branch (a _discarded statement_) of a constexpr if is not instantiated. Outside of templates the branch is instantiated. – 1201ProgramAlarm Dec 25 '20 at 17:04
  • @1201ProgramAlarm Ahh, "is not instantiated", that makes perfect sense. – Zebrafish Dec 25 '20 at 17:08
  • Not quite a dup, but [this question](https://stackoverflow.com/questions/58300760/wrong-understanding-of-if-constexpr) covers why it isn't discarded outside the template. – 1201ProgramAlarm Dec 25 '20 at 17:15

0 Answers0