2016-06-13 16 views
0

이 문제를 이해하는 데 다소 시간이 걸렸지 만, boost::any의 의미는 혼란 스럽습니다. 값 형식으로boost :: 포인터와의 혼란 vs 값

, 당신과 같이 사용 :

int value = 100; 
boost::any something; 
something = value; 
//...later... 
int value = boost::any_cast<int>(&something); 

이 코드는 내부적으로 사본으로 value 명확하고 의미가 있지만 저장합니다. 즉, 더 큰 오브젝트의 경우 내부에 boost::any을 넣으면 복사됩니다. 또한 void*으로 대체하는 함수는 boost::any 오브젝트에 포함 된 값을 수정할 때 함수 외부의 값이 수정 될 것으로 예상됩니다 (복사 한 이후에는 발생하지 않음). 나는 그것으로 포인터를 넣을 경우

그래서, 상황이 이상한 얻을 :

int value = 100; 
boost::any something; 
something = &value; 
//...later... 
int* value = *boost::any_cast<int*>(&something); 

내가 반환 값 역 참조가이 경우에 boost::any_cast 반환 int** 때문에! 나는 또한 체크하지 않았다. 그러나 이것이 something.empty() == true 인 경우 충돌 할 수 있다고 생각한다. 이것은 전혀 간단하지 않습니다.

값을 내 boost::any에 저장하고 싶지 않습니다. 포인터에서만 작동하고 의미 상으로는 void*에 가깝게 동작해야합니다. 포인터가, 밖으로 포인터, 일부 형식 안전 함께. 기본적으로 내가 원하는 것은 boost::any_pointer, 또는 이와 비슷한 것입니다. boost::any에서 포인터를 제외한 모든 것을 허용하지 못하도록 할 수 있습니까? 그리고 그렇지 않다면, 내가 찾고있는 의미를 줄 수있는 boost::any에 대한 대안이 있습니까?

+0

'boost :: any'는 꽤 e이다. asy를 생성 한 다음 의미를 바꿀 수 있습니다. –

+0

첫 번째 스 니펫이 작동하지 않고 dereferencement (as snippet2)가 필요합니다. [Demo] (http://coliru.stacked-crooked.com/a/df5bdb307f56b709) – Jarod42

+0

클래스에서'boost :: any'를 포인터 만 허용. – Jarod42

답변

1

참고 : 나는 당신이 (존재하지만) boost::any_pointer의 라인에 뭔가를 찾고 있기 때문에 당신이 boost::any에 포인터를 저장할 가정입니다.

boost::any_cast은 내부에 저장된 실제 값 (홀더 내부의 held 개체)에 대한 포인터를 반환합니다. 따라서 실제로 복사하지 않는 한 사본을 저장합니다.

template<typename ValueType> 
    ValueType * any_cast(any * operand) BOOST_NOEXCEPT 
    { 
     return operand && operand->type() == boost::typeindex::type_id<ValueType>() 
      ? &static_cast<any::holder<BOOST_DEDUCED_TYPENAME remove_cv<ValueType>::type> *>(operand->content)->held 
      : 0; 
    } 

당신은 항상에만 포인터 타입을 허용 boost::any 주위에 래퍼를 만들 수 있습니다

class MyAny { 
public: 
    template <typename T, 
     typename = typename std::enable_if<std::is_pointer<std::remove_cv<T>::type>::value>::type> 
    MyAny(T ptr): any_(ptr) {} 

template <typename ValueType> 
ValueType operator*() { 
    return *boost::any_cast<ValueType>(&any_); 
} 

private: 
    boost::any any_ 
}; 

위는 거친 코드 나는 컴파일하고 테스트하지 않았습니다.

std::enable_if 형질은 C++ 11에서 사용할 수 있지만 부스트에서도 찾을 수 있습니다. 그것은 여러분의 MyAny을 오직 포인터 타입으로 제한 할 것입니다.

1

any_cast를 잘못 사용하고 있습니다.

본질적으로 2 개의 맛이 있습니다.

  • 모든 참조를 취하고 임의의 포인터를 취하는 콘텐츠
  • 에 값 또는 참조를 반환하고, 콘텐츠에 대한 포인터를 리턴

예 :

#include <boost/any.hpp> 
int main() 
{ 
    // Any holding a value 
    { 
     boost::any any_value(1); 
     // Throws bad_any_cast if the content is not 'int' (in this case): 
     int value = boost::any_cast<int>(any_value); 
     // Throws bad_any_cast if the content is not 'int' (in this case): 
     int& reference = boost::any_cast<int&>(any_value); 
     // Returns a null pointer if the content is not 'int' (in this case): 
     int* pointer = boost::any_cast<int>(&any_value); 
    } 

    // Any holding a pointer (which is nothing else but a value) 
    { 
     int integer = 0; 
     boost::any any_ptr(&integer); 
     // Throws bad_any_cast if the content is not 'int*' (in this case): 
     int * pointer = boost::any_cast<int*>(any_ptr); 
     // Throws bad_any_cast if the content is not 'int*' (in this case): 
     int*& pointer_reference = boost::any_cast<int*&>(any_ptr); 
     // Returns a null pointer if the content is not 'int*' (in this case): 
     int** pointer_pointer = boost::any_cast<int*>(&any_ptr); 
    } 
} 

또한보십시오 : http://en.cppreference.com/w/cpp/experimental/any 그리고 http://en.cppreference.com/w/cpp/experimental/any/any_cast

+0

그 구문은 많은 사람들을내어 버리는 것을 보았습니다. 그것은 std :: any에도 동일합니다. –

+0

'boost :: any'를 사용하는 동안 예외를 피하려고합니다. 그래서 포인터 오버로드를 사용하고 있습니다. 첫 번째와 두 번째 예제는 예외를 던지는 것처럼 보입니다. 적어도 내 테스트에서는 그렇게했다. –

+0

다음은 내가 던지는 예제입니다. 나는 그것을 던지고 싶지 않아, 만약 형식이 잘못되면'nullptr'이 반환되기를 원합니다 : http://coliru.stacked-crooked.com/a/f6ffdf4387e335d6 –