最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

language lawyer - Should this example for non structural constexpr C++ argument compile? - Stack Overflow

programmeradmin2浏览0评论

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
  • 2 Related to can-i-use-a-constexpr-value-in-a-lambda-without-capturing-it. – Jarod42 Commented Mar 18 at 17:17
  • Lambda doesn't capture, so compiler shouldn't find non_structural_value declaration and thus throw an error. – kiner_shah Commented Mar 19 at 6:52
Add a comment  | 

1 Answer 1

Reset to default 4

This 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.

发布评论

评论列表(0)

  1. 暂无评论