2016-06-21 2 views
7

This page은 C++ 17의 make_optional 함수가 constexpr optional<...>을 반환한다고 말합니다. 나는 (비록 내가 틀릴 수도있다) 이것은 optional<T>constexpr 복사 또는 이동 생성자가 있어야한다고 생각한다. 그러나 this page은 그렇지 않습니다.C++ 17 make_optional constexpr-ness

현재 C++ 1z 초안이 현재있는 것처럼 make_optional을 어떻게 구현할 수 있는지 알 수 없습니다. 설명을 위해 this post을 참조하십시오. 몇 가지 해결 방법이 있습니까, 아니면 그냥 표준 초안/cppreference의 실수입니까?

+0

이 질문에 대해서는 의문의 여지가 없습니다. – immibis

+0

@immibis 업데이트 됨 : –

+1

cppreference가 'constexpr'을 허공에서 꺼내지 않았다고 알고 있습니다 ... –

답변

2

@ Yakk 및 @ T.C에게 감사드립니다. 그들의 설명을 위해.

struct wrapper { 
    int value; 

    // non-explicit constexpr constructor 
    constexpr wrapper(int v) noexcept : value(v) {} 

    // non-constexpr copy & move constructors 
    wrapper(const wrapper& that) noexcept : value(that.value) {} 
    wrapper(wrapper&& that) noexcept : value(that.value) {} 
}; 

constexpr wrapper make_wrapper(int v) 
{ 
    return {v}; 
} 

int main() 
{ 
    constexpr auto x = make_wrapper(123); // error! copy/move construction, 
              // but no constexpr copy/move ctor 

    constexpr int y = make_wrapper(123).value; // ok 
    static_assert(y == 123, "");    // passed 
} 

을 그래서 make_wrapper 성공적으로 constexpr wrapper 반환 않는다 : 나는 일을 명확하게해야한다 예를 들어 느낌 constexpr 복사/이동 생성자가 없기 때문에 코드가 컴파일되는 것을 방지하는 것은 복사/이동 구조입니다 (일반적으로 컴파일러에 의해 생략 됨).

반환 된 (임시) wrapper의 개체의 값을 constexpr 변수로 초기화하여 확인할 수 있습니다.

1

return {something};을 사용하여 C++ 11의 반환 값을 직접 생성 할 수 있습니다. constexpr 인 비 명시적인 ctors가있는 경우 함수에서 반환 할 수 있습니다.

+0

필자는 그것이 복사 - 추출에 의한 착각이라고 생각합니다. copy-elision이 없으면 컴파일되지 않습니다 : [gcc] (https://godbolt.org/g/X3pTzv), [clang] (https://godbolt.org/g/AiqxxV). –

+0

그리고 내가 언급 한 링크 된 게시물의 답은 컴파일러가 복사 - 추출을 수행한다고 할지라도'constexpr' 복사/이동 생성자는 여전히 액세스 할 수 있어야합니다 (결국 사용하지 않더라도). –

+0

@ ZizhengTai 다른 사본을 만드는 것은 자신의 모범적 인 잘못입니다. https://godbolt.org/g/jT7mHd 사본 목록 초기화는 개념적 또는 다른 방법으로 임시 자료를 만들지 않습니다. –