2014-11-22 4 views
5

복사 생성자가 constexpr 인 클래스를 작성했습니다. (예를 들어, 구조체가 단순 해집니다.) 필드 중 하나가 배열입니다. 나는 그것을 또한 원해.constexpr 생성자의 배열 복사

struct Foo 
{ 
    static constexpr int SIZE = 4; 
    constexpr Foo() = default; 
    constexpr Foo(const Foo &foo) : 
      arr{foo.arr[0], foo.arr[1], foo.arr[2], foo.arr[3]}, 
      bar(foo.bar+1) {} 
    int arr[SIZE] = {0, 0, 0, 0}; 
    int bar = 0; 
}; 

내 버전은 작동하지만 확장 가능하지 않습니다. SIZE을 변경하면 생성자를 수정해야합니다. 또한 코드가보기 흉하게 보입니다.

생성자에서 배열을 복사하는 더 좋은 방법이 있습니까? 생성자는 constexpr이어야합니다.

+7

아무튼에게 기본 복사 생성자가 작업을 수행하지 않습니까? – juanchopanza

+0

constexpr은 배열이 변이되지 않는다고 보장하지 않습니까? 포인터 만이 아니라 값으로 복사하는 것이 왜 효과가 있습니까? – tohava

+0

@juanchopanza 솔직히 내 마음을 넘지 않았다. 그러나 문제는 질문입니다. 클래스에 복사를 위해 일부 계산이 필요한 일부 필드가 있다고 가정 할 수 있습니다. 게다가 그것은 미래에있을 가능성도 있습니다. –

답변

3

std :: array를 사용할 수 있습니다. 집계 유형이므로이 방법이 효과적 일 것이라고 생각합니다. C++ 14에서

+0

좋은 답변이지만 직접 할 수있는 방법을 알고 싶습니다. –

3

당신은 단지 배열을 복사하는 루프를 사용할 수 있습니다

constexpr Foo(const Foo &foo) 
    : bar(foo.bar + 1) 
{ 
    for (int i = 0; i < SIZE; ++i) 
     arr[i] = foo.arr[i]; 
} 

당신이을 을해야 의미하지 않는다. 대신 std::array을 사용하는 것이 좋습니다. 예를 들어, arr이 평범하지 않은 초기화가있는 일부 클래스 유형의 배열 인 경우 std::array 및 기본 복사 생성자를 사용할 때 복사 초기화 대신 성능이 낭비되어 기본 초기화되고 복사됩니다.

+0

죄송합니다. C++ 11입니다. –

+3

비록 C++ 14에서도 훌륭한 일반적인 접근 방식은 아니지만 각 배열 요소를 복사 구성하는 것이 아니라 각 배열 요소에 할당합니다. 그것은'int'의 배열 일 때는 중요하지 않지만 다른 타입의 경우에는 중요합니다. – hvd

1

당신처럼 뭔가를 할 수 C++ 11 단지 배열

template <int LENGTH> 
constexpr bool copy_array(const char (&from)[LENGTH + 1], char (&to)[LENGTH], int index) 
{ 
    return index < LENGTH ? (to[index] = from[index], copy_array(from, to, ++index)) : false; 
} 

constexpr char src[] = "ab"; 
char dest[2]; 
copy_array(src, dest, 0); 

편집 복사하려면 : 그리고 당신의 맥락에서, 당신은 같은 것을 할 수 있습니다

#include <iostream> 
#include <type_traits> 
#include <array> 
#include <utility> 

struct Foo 
{ 
    static constexpr int SIZE = 4; 
    constexpr Foo() = default; 
    constexpr Foo(const Foo &foo) : 
      arr{foo.arr}, 
      bar(foo.bar + 1) {} 
    std::array<int, SIZE> arr = {{0, 0, 0, 0}}; 
    int bar = 0; 
}; 

int main() 
{ 
    constexpr Foo foo1; 
    constexpr Foo foo2(foo1); 

    std::cout << foo1.bar << std::endl; 
    std::cout << foo2.bar << std::endl; 

    return 0; 
} 
+0

예제에 전체 생성자 정의를 포함시킬 수 있습니까? –

+0

constexpr 클래스 생성자의 컨텍스트에서 시도했지만 쉽지 않습니다. 그리고 다른 방법이 있습니다 : template struct Foo {template constexpr Foo (Args && ... args) : data {args} {} char data [LENGTH];}; – xiaodong

+0

이것이 내 문제를 어떻게 해결할 수 있는지 알 수 없습니다. –