Discussion:
Why does this not compile ?
Add Reply
Bonita Montero
2024-08-23 16:52:10 UTC
Reply
Permalink
#include <iostream>
#include <atomic>

using namespace std;

int main()
{
struct S { int x; };
constexpr bool SUBST = sizeof(S) == sizeof(atomic<S>);
conditional_t<SUBST, atomic<S>, char> as;
if constexpr( !SUBST )
as = 123;
}

as is tried to compiled although SUBST is false.
Sam
2024-08-23 23:12:44 UTC
Reply
Permalink
Post by Bonita Montero
#include <iostream>
#include <atomic>
using namespace std;
int main()
{
struct S { int x; };
constexpr bool SUBST = sizeof(S) == sizeof(atomic<S>);
conditional_t<SUBST, atomic<S>, char> as;
if constexpr( !SUBST )
as = 123;
}
as is tried to compiled although SUBST is false.
Because SUBST is false, as is a

std::atomic<S>

Therefore for

as = 123;

to compile there must be a suitable operator= overload defined. There is
none. std::atomic will supply an operator= that will take a const S & as a
parameter, so

as = S{123};

will compile. However, a plain, unadorned 123 will require two implicit
conversions to arrive to its happy place, but only one implicit conversion
is allowed, of course.
Bonita Montero
2024-08-24 02:48:16 UTC
Reply
Permalink
Post by Sam
Post by Bonita Montero
#include <iostream>
#include <atomic>
using namespace std;
int main()
{
    struct S { int x; };
    constexpr bool SUBST = sizeof(S) == sizeof(atomic<S>);
    conditional_t<SUBST, atomic<S>, char> as;
    if constexpr( !SUBST )
        as = 123;
}
as is tried to compiled although SUBST is false.
Because SUBST is false, as is a
No, SUBST is true. And the code unter an if consexpr then must be
syntactically correct, not semantically.
Post by Sam
std::atomic<S>
Therefore for
as = 123;
to compile there must be a suitable operator= overload defined. There is
none. std::atomic will supply an operator= that will take a const S & as
a parameter, so
as = S{123};
will compile. However, a plain, unadorned 123 will require two implicit
conversions to arrive to its happy place, but only one implicit
conversion is allowed, of course.
Bonita Montero
2024-08-24 03:14:39 UTC
Reply
Permalink
I've got it: if constexpr () compiles all branches, except
in a templated function. This would be a right code:

#include <iostream>
#include <atomic>

using namespace std;

int main()
{
auto fn = []<typename T>()
{
struct S { T x; };
constexpr bool SUBST = sizeof(S) == sizeof(atomic<S>);
conditional_t<SUBST, atomic<S>, char> as;
if constexpr( !SUBST )
as = 123;
};
fn.template operator ()<int>();
}

Loading...