2013-09-04 3 views
1

공용체에 저장된 매개 변수의 수가 다른 함수가있는 클래스를 정의하려고합니다. 클래스는 함수 객체와 필요한 매개 변수로 초기화됩니다. 나는 위치에서이 컴파일러 오류가 표시된 얻고있다 (1)과 (2)C++에서 union과 함께 std :: function 사용

변형 필드 'f_V'이 아닌 사소한 소멸자

(2를 가지고 있기 때문에 '_'암시 적으로 삭제의

(1) 소멸자) 필드 'functions'에 삭제 된 소멸자가 있기 때문에 'MyClass'의 소멸자가 암시 적으로 삭제됩니다.

단순히 다른 함수 객체의 공용체를 선언하고 전달 된 매개 변수에 따라 적절한 함수를 선택하고 불러라. 이러한 오류가 발생하는 이유는 무엇이며 어떻게이 코드를 다시 작성해야합니까?

template<typename VARIABLE> struct MyClass { 
    MyClass(VARIABLE *p, const std::function<void (VARIABLE&)>& f) { 
     functions.f_V = f; 
     ... 
    } 
protected: 
    union _ { 
     std::function<void (VARIABLE &)> f_V; // (1) 
     std::function<void (const VARIABLE &, VARIABLE &)> f_vV; 
     std::function<void (const VARIABLE &, const VARIABLE &, VARIABLE &)> f_vvV; 
     std::function<void (const VARIABLE &, const VARIABLE &, const VARIABLE &, VARIABLE &)> f_vvvV; 
    } functions; // (2) 
    ... 
}; 

편집 : 나는 용기에 변수 인수 목록을 가진 람다 함수의 스토리지를 달성하기 위해 노력하고 있습니다. 이런 식으로 뭔가 :

std::vector<MyClass<MyVariable>> myContainerOfLambdas; 
MyVariable A,B,TO; 
auto lambda1 = [this](const MyVariable& a, MyVariable& to) { ... }; 
myContainerOfLambdas.push_back(MyClass<MyVariable>(A,TO,lambda1)); 
auto lambda2 = [this](const MyVariable& a, const MyVariable& b, MyVariable& to) { ... }; 
myContainerOfLambdas.push_back(MyClass<MyVariable>(A,B,TO,lambda2)); 
... 
// iterate over the stored MyClass objects holding the lamda functions and the parameters 
// to call them 
for(MyClass<MyVariable> & e:myContainerOfLambdas) { 
    e(); // here the appropriate lambda function will be invoked with the appropriate values 
    // stored in MyClass 
} 

참고 : 간결 나는 MyClass에의() 연산자의 정의를 생략했지만, 단순히 올바른 매개 변수를 사용하여 올바른 함수 객체를 호출합니다.

더 나은 디자인 접근 방식을 보려면 올바른 방향으로 나를 안내해주십시오. 감사!

+0

나쁜 아이디어. 함수는 복합 형을 유지할 수 있기 때문에 컴파일러가 어떤 함수 객체 (있는 경우)가 조합이 파괴 될 때 파기되는지 어떻게 알 수 있습니까? –

+0

기본 생성시 함수 객체가 '비어 있습니다'라고 생각합니다. 컴파일러는 각 공용 멤버의 소멸자를 호출합니다. 해당 구성원 중 하나만 비어 있습니다. – andrewz

+3

C++에서'union '을 사용하지 마십시오. 대신'boost :: variant'를 사용하십시오. 'union '은 C 코드에서만 사용해야합니다. –

답변

1

C++ 11의 unrestricted unions feature을 원하는대로 사용할 수 있습니다. 적절한 액티브 멤버를 구성/삭제하는 공용체에서 사용자 정의 생성자 및 소멸자를 구현해야합니다.

+0

당신은 아마 (un-union) 클래스에 (익명의) union 유니온으로 embed시켜야 할 것입니다. 공용체에는 빈 dtor가있을 것이고 활성 멤버에 대한 명시적인 dtor 호출은 주변 클래스의 dtor에서 수행됩니다. – dyp

+0

@DyP : 소멸자가 활성 멤버에 대한 인덱스에 액세스해야하고 인덱스가 유니온의 멤버가 될 수 없으므로 정확합니다. –

+0

@ user1131467 : 그리고 정말로, 일단 모든 작업을 완료하면 간단히'boost :: variant'를 재 작성했을 것입니다. –

관련 문제