template < class... T >
int f1(int(*f2)(T...),vector <void* > v);
vector v의 각 원소들을 T 포인터로 캐스팅한 후에 f2에 넣은 것을 반환하는 함수를 만들고 싶습니다.
v의 원소들을 T포인터로 캐스팅해 tuple로 만드는 것만 할 줄 알면 쉽게 풀릴거 같은데 많이 어렵습니다.
재미있게 잘 읽었습니다. 참고로, C++11 뿐만 아니라 C++14도 사용가능한 상황이라면, gens를 직접 작성하시는 대신 C++14에 추가된 std::integer_sequence (그리고 그 사용을 편리하게 하는 std::make_index_sequence 등)을 사용하시는 게 편하실 겁니다.
이게 되나요...?!
C++03 시절에도 템플릿은 제 C++ 프로그래밍 지식/경험의 끝자락에 가까스로 걸치던 물건이었습니다만, C++11 이후로는 아예 넘사벽이로군요.
근데 아무리 그래도 템플릿 매개변수는 컴파일 타임에 결정이 되어야 할 텐데, vector의 길이는 런타임에나 결정될 수 있는 것 아니던가요?
이게 되면 정말 제 상식을 뛰어넘겠군요. 파이썬도 아니고 C++에서 런타임에 결정되는 함수 시그너쳐라...
근데 왜 f2가 벡터 매개변수를 받게 작성하시지는 않는 거죠? 그거라면 아주 간단히 될 텐데요.
저도 처음 보는 물건이었는데,정식 명칭이
저도 처음 보는 물건이었는데,
정식 명칭이 "variadic templates" 이네요.
꼬리-재귀함수 와 비슷한 형태를 컴파일 시간에 완성해주는 물건인가 봅니다.
여기에 자세히 설명되어 있습니다.
http://eli.thegreenplace.net/2014/variadic-templates-in-c/
밑은 위 사이트의 예제에 조금 틀린 게 있어서 수정해보았습니다.
그나저나, 꺽쇠는 어떻게 해야하죠...
이런 게 있다고는 들어서 알긴 했지만
그래도 여전히 파라미터 갯수는 컴파일 타임에 결정이 되는 꼴이죠.
pair_comparer(1, 1, 1, 2)
처럼 말입니다. (이 경우엔 최대 4개)파라미터 갯수 자체가 런타임에서야 결정되는 경우에는 컴파일 타임에 할 수 있는 게 없지 않습니까?
미리 다 만들어 놓을 수도 없고...
음? 런타임에 가능한 것 처럼 들렸나요?저도
음? 런타임에 가능한 것 처럼 들렸나요?
정확한 스펙은 확인 해 보지 않았지만, 저도 컴파일 타임에만 가능할 것이라 생각합니다.
미흡 하지만 답변 달아 보겠습니다.
말씀 하신 방법에 대해서 딱 떨어지는 해결법이 떨오르질 않네요. 대신 약간 전제 조건을 수정함으로 써 해결하는 방법을 3가지 작성해 보았습니다.
1. std::vector를 사용하지 않을 경우
std::vector를 반드시 사용해야하는게 아니라면 아래와 같은 방법을 사용할 수 있습니다.
2. std::tuple을 f2의 파라미터로 사용할 경우
std::vector를 쓸수 밖에 없는 상황에서 std::tuple을 이용한다면 아래와 같은 방법도 사용할수 있습니다.
3. 부수적인 코드를 동반할 수 있을 경우
이 방법이 사용하는 측면에선 말씀하셨던 형태 그대로 사용할 수 있긴하나 부수적인 코드가 많아지는 문제가 있겠네요.
작성자입니다
불가능하진 않습니다. 방법을 찾아냈네요
여러분도 좋은공부가 되셨으면 합니다.
캬...
위에 익명 단 사람입니다. 입증할 방법은 없지만요. 그나저나 C++에서 functional programming을 보다니...
TMP의 달인이신 것 같네요. 저는 이 정도 수준의 코드는 읽기도 벅찹니다.
대충 파악하기로는 결국 파라미터의 갯수는 주어진 함수(f)의 타입으로부터 주어지는 것이고(T...),
핵심은 파라미터의 순서에 대응하는 서수들을 제공해주는 가변 템플릿을 만드는 것이었군요.
그걸 만드시느라 gens 구조체를 만드신 거고요.
기막힌 코드 잘 봤습니다. 제가 놓치고 있는 TMP의 세계를 엿볼 수 있었네요. 아 이거 공부해야 되는데 -_-;;;
재미있게 잘 읽었습니다.
재미있게 잘 읽었습니다. 참고로, C++11 뿐만 아니라 C++14도 사용가능한 상황이라면,
gens
를 직접 작성하시는 대신 C++14에 추가된std::integer_sequence
(그리고 그 사용을 편리하게 하는std::make_index_sequence
등)을 사용하시는 게 편하실 겁니다.tuplecall
의 역할을 하는std::apply
도 C++17에 추가될 예정이라고 합니다. libstdc++이나 libc++ 최신 버전을 사용 중이시라면 C++17이 나오기 전이라도std::experimental::apply
를 대신 사용할 수 있습니다.댓글 달기