, 하지만 어쩌면 나는 그것을 구현하려고 할 때 발생할 수있는 기술적 인 장애물에 대해 암시 할 수 있습니다. 그것은 당신에게 전문화가 왜 없는지에 대한 느낌을 줄 수 있기를 바랍니다.
먼저 std::function<>
클래스 템플릿 자체를 구현할 수있는 방법을 생각해 봅시다. 다음과 같이 설계의 기초가되는 유형의 삭제 방법은 (실제 구현 방법이 더 복잡 이것은 단지 예시 단순화입니다) 스케치 할 수 있습니다 :
#include <memory>
template<typename T>
struct function { };
template<typename R, typename... Args>
struct function<R(Args...)>
{
public:
template<typename F>
function(F&& f) : _holder(
new holder<typename std::decay<F>::type>(std::forward<F>(f))
)
{ }
R operator() (Args&&... args)
{ _holder->call(std::forward<Args>(args)...); }
private:
struct holder_base
{ virtual R call(Args&&... args) = 0; };
template<typename F>
struct holder : holder_base
{
holder(F&& f) : _f(std::forward<F>(f)) { }
R call(Args&&... args) { return _f(std::forward<Args>(args)...); }
F _f;
};
std::unique_ptr<holder_base> _holder;
};
을 이제 타원의 전문화가 실제로 어떻게 보이는지 확인해 보겠습니다 . 무엇보다도 variadic 함수에 제공되는 인수의 수와 유형은 이 아니며 해당 함수의 서명이이 아닙니다. 이것은 우리를 강제로
template<typename R, typename... Args>
struct function<R(Args.......)>
{
...
template<typename... Ts>
R operator() (Args&&... args, Ts&&... ts)
{ _holder->call(std::forward<Args>(args)..., std::forward<Ts>(ts)...); }
...
, 차례로, holder<>
의 호출 연산자 가변 인자 함수 템플릿 만들기 : 따라서, 우리의 전문 템플릿의 호출 연산자는 인수의 수와 종류를 받아들이는 함수 템플릿해야합니다. 그러나 형식 지우기를 실현하려면 동일한 호출 연산자가 virtual
이어야하며 함수 템플릿은 C++에서 virtual
이 될 수 없습니다.
variadic 인수 (여기서 생략 부호에 대해 말하고 있습니다.)는 가변적 인 템플릿 매개 변수와 완벽한 전달로 재귀하지 않고도 쉽게 전달할 수 있습니다. 나는 그것을 달성하는 간단한 방법을 알지 못한다. 특히 variadic list와 일치하는 인수가 아닌 다른 인수가 함수에 전달되지 않는다면 특히 그렇다.
작동 여부를 확인하는 템플릿을 테스트 해 보셨습니까? – Omnifarious
두 개의 스 니펫 모두 완전히 다른 것을 보여줍니다. Variadic 템플릿은 컴파일 할 때 처리됩니다. "C"스타일 변수 인수는 런타임에 처리됩니다. – mfontanini
'...'(variadic 템플릿이 아님) 매개 변수 구문은 C와의 하위 호환성을 위해 유지됩니다. 사용법은 권장하지 않습니다. –