I have the following code from Ben Deane talk.
#define CX_VALUE(...) [] { \
struct { \
constexpr auto operator()() const noexcept { return __VA_ARGS__; } \
using cx_value_tag = void; \
} val; \
return val; \
}()
template <typename T>
concept cx_value = requires { typename T::cx_value_tag; };
auto func(cx_value auto x) {
constexpr auto val = x();
std::cout << "Constexpr value: " << val.val() << '\n';
}
class S {
public:
constexpr S(const int val) : val_(val){}
int val() const {
return val_;
}
private:
int val_;
};
int main() {
constexpr S non_structural_value{420};
func(CX_VALUE(non_structural_value));
}
Issue is that clang rejects it, gcc accepts it.
Which compiler is right(or is it maybe underspecified in the standard)?
I have the following code from Ben Deane talk.
#define CX_VALUE(...) [] { \
struct { \
constexpr auto operator()() const noexcept { return __VA_ARGS__; } \
using cx_value_tag = void; \
} val; \
return val; \
}()
template <typename T>
concept cx_value = requires { typename T::cx_value_tag; };
auto func(cx_value auto x) {
constexpr auto val = x();
std::cout << "Constexpr value: " << val.val() << '\n';
}
class S {
public:
constexpr S(const int val) : val_(val){}
int val() const {
return val_;
}
private:
int val_;
};
int main() {
constexpr S non_structural_value{420};
func(CX_VALUE(non_structural_value));
}
Issue is that clang rejects it, gcc accepts it.
Which compiler is right(or is it maybe underspecified in the standard)?
Share Improve this question asked Mar 18 at 17:03 NoSenseEtAlNoSenseEtAl 30.3k32 gold badges149 silver badges322 bronze badges 2 |1 Answer
Reset to default 4This has nothing to do with the properties of the class S
.
The problem can be reduced to
struct S {};
int main() {
constexpr S s{};
[]{
struct {
constexpr auto operator()() { return s; }
} val;
};
}
The problem is that s
is being odr-used here in return s;
because it doesn't have the lvalue-to-rvalue conversion applied to it (because it is of class type). And s
is not odr-usable in this scope.
For the same reason you would need to capture s
if you tried to write []{ return s; }
instead. But in the case above capturing won't help either, s
will still not be odr-usable in the scope of the local class.
Clang is correct.
non_structural_value
declaration and thus throw an error. – kiner_shah Commented Mar 19 at 6:52