0

std::map< std::string, boost::any >OptionsMap이고 모든 유형 (따라서 템플릿)을 가져 와서 맵에 저장하는 기능을 만들고 싶습니다. 다음 코드가 작동합니까?템플릿 및 rvalues ​​참조를 매개 변수로 사용하기

template <typename T> 
void Set(std::string optionName, T&& optionValue) 
{ 
    OptionsMap[optionName] = optionValue; 
} 
+0

작동하지 않는다고 생각하는 이유가 있습니까? –

+3

완벽한 포워딩을 원한다면'std :: forward' 호출을 놓쳤습니다. – chris

+0

@KerrekSB 나는 여전히 rvalues ​​등을 배우고있어, 그래서 난 단지 확인하고 싶었어 – ReBirTH

답변

3

일반적으로 함수 템플릿이 범용 참조 (예 : 추론 된 유형의 참조 값)를 허용하는 경우 인수에 제공된 값 범주와 동일한 값 범주를 얻기 위해 forward 함수 매개 변수를 캐스팅해야합니다 함수 호출에 :

template <typename T> 
void Set(std::string optionName, T&& optionValue) 
{ 
    OptionsMap[optionName] = std::forward<T>(optionValue); 
    //      ^^^^^^^^^^^^^^^ 
} 

매개 변수 optionValue 자체는 캐스팅하지 않고, 그래서 당신이 이동해야 것의 복사본을 만드는 것, 항상 좌변입니다. 유형이 복사 가능하면 예상보다 효율적이지 않습니다. 유형을 복사 할 수없는 경우 (예 : unique_ptr) 악화됩니다. 이제 함수가 이후에 컴파일에 실패하는 인수를 허용합니다.

+0

고마워! forward 함수는 올바르게 이해하면 lvalue에서 rvalue를 반환합니다. – ReBirTH

+2

@ user3027108 : 아니요. 그것은'std :: move' 일 것입니다. 대조적으로,'std :: forward'는 명백한 템플릿 인자가 주어져야하고, 원래 인자의 올바른 일반화 된 값 범주를 복원합니다. 예 : [이 답변] (http://stackoverflow.com/a/3582313/596781)을 참조하십시오.) –

+0

'optionName' 인자는 lvalue reference가 아니 어서'std :: string' 카피를 생성하지 않아야합니까? – ReBirTH

1

물론. 왜 효과가 없을까요?

boost::any::operator=ValueType을 만족하는 모든 데이터 형식의 인수를 허용합니다.

boost::any이 이동 의미 체계를 지원하기 시작하면 순방향 호환성을 위해 값을 들여서 이동하려고합니다. 이 때, 가동 그것을을 이동이 함수 r- 수치로 전달

template <typename T> 
void Set(std::string optionName, T optionValue) 
{ 
    OptionsMap[optionName] = std::move(optionValue); 
} 

. 그것은 표준에 의해 보장됩니다.

+0

그래,하지만 가장 효율적이고 정확한 방법일까요? – ReBirTH

+0

@ user3027108 그렇지 않다면 왜 제안하겠습니까? – rightfold

+0

@rightfold OP는 'T'를 'T &&'(범용 참조)로 언급합니다. 당신은 값으로 복사본을 작성하여 복사본을 작성하고 있습니다. –