2017-09-14 3 views
7

해당 클래스의 특정 생성자에 대해 특정 클래스 유형에 대해 make_shared의 별명을 지정하려고 시도합니다. 내 최고의 시도 :오버로드 된 템플릿 함수의 Constexpr 별칭

class foo { public: foo(int x) : y(x) {} int y; }; 
constexpr auto newfoo = static_cast<std::shared_ptr<foo>(*)(int)>(std::make_shared<foo>); 

수익률 : 내가 잘못 뭐하는 거지

error: invalid static_cast from type ‘<unresolved overloaded function type>’ to type ‘std::shared_ptr<foo> (*)(int)’ 
constexpr auto newfoo = static_cast<std::shared_ptr<foo>(*)(int)>(std::make_shared<foo>); 

?

답변

4

std::make_shared가변 인자 템플릿이다. 템플릿 매개 변수로 <foo> 만 지정하고 있지만 어딘가에 int이 필요합니다. 어쨌든 make_shared의 템플릿 인수가 배치 된 방법과 C++의 오버로드 집합을 사용하는 것이 일반적으로 번거롭기 때문에 사용자의 접근 방식은 실패 할 것입니다. 쓰기, 읽고, 이해하기 쉽게 내 의견으로는

constexpr auto newfoo(int x) 
{ 
    return std::make_shared<foo>(x); 
} 

: I 제안 무엇

대신 래퍼 함수를 ​​만드는 것입니다. 당신이 정말 SFINAE 편의와 noexcept 필요한 경우 repeat the body three times 수 : 매크로 위의 선언이 덜 고통스러운 수 있도록하는 데 사용할 수 있습니다

constexpr auto newfoo(int x) 
    ->   decltype(std::make_shared<foo>(x)) 
     noexcept(noexcept(std::make_shared<foo>(x))) 
     {   return std::make_shared<foo>(x); } 

. 당신은 Args...에 대한 T=foo 무언가를 제공해야

template< class T, class... Args > 
shared_ptr<T> make_shared(Args&&... args); 

:

auto newfoo = 
    static_cast<std::shared_ptr<foo>(*)(const int&)>(
     &std::make_shared<foo, const int&>); 

make_shared의 선언에 당신이 정말로 함수 포인터를 원하는 경우


,이 작동하는 것 같다 . Args...은 전달 참조 팩이므로 항상 왼쪽 값 참조 또는 왼쪽 값으로 추론합니다. 이것이 <foo, const int&>이 유효한 템플릿 매개 변수 집합이고 <foo, int>이 아닌 이유입니다.

constexpr auto newfoo = &std::make_shared<foo, const int&>; 

캐스트는 정말 여기에 필요하지 않습니다 : 코멘트에 지적

Zefick,이 모든 단순화 할 수있다.

+1

+1하지만, "if you really to to"예제에서'int &&'대신'const int &'를 사용해야합니다. 있는 그대로,'const int i = 42; 자동 f = newfoo (i);'는 작동하지 않습니다. –

+0

@MilesBudnek : 좋은 지적, 내 대답을 바 꾸었습니다. –

+2

'constexpr auto newfoo = std :: make_shared '그냥 작동합니다. 왜 캐스팅이 필요한거야? – Zefick

관련 문제