当玩好的ol' c++
我开始想知道是否可以基于封闭模板重载模板函数。在第一层,这看起来是可以实现的,但是,如何递归地完成?所以下面的伪c ++代码
#include <iostream>
#include <vector>
#include <map>
template <typename T> void magic(){
std::cout << "Called magic<T>" << std::endl;
}
template <typename std::vector<T> > void magic(){
std::cout << "Called magic<std::vector<T> >" << std::endl;
magic<T>();
}
template <typename std::map<T,U> > void magic(){
std::cout << "Called magic<std::map<T,U> >" << std::endl;
magic<T>();
magic<U>();
}
int main() {
magic<std::vector<std::map<std::string,std::vector<int> > > >();
}
产生类似的东西:
Called magic<std::vector<T> >
Called magic<std::map<T,U> >
Called magic<T>
Called magic<std::vector<T> >
Called magic<T>
原则上,这看起来不应该是不可能的,因为所有类型信息在编译时都可用。编译器可以轻松创建所有必需的函数,因为递归必然会停止。因此问题:这可能吗?如果是这样,怎么样?
答案 0 :(得分:3)
简单的专业化应该可以解决问题,但请记住,你不能部分地专门化函数模板,所以你需要一个中间类模板:
template <typename> void magic();
template <typename T>
struct Impl
{
static void f() { std::cout << "Primary template\n"; }
};
template <typename T, typename A>
struct Impl<std::vector<T, A>>
{
static void f() { std::cout << "A vector\n"; magic<T>(); }
};
template <typename K, typename T, typename P, typename A>
struct Impl<std::map<K, T, P, A>>
{
static void f() { std::cout << "A map\n"; magic<K>(); magic<T>(); }
};
template <typename T> void magic() { Impl<T>::f(); }
答案 1 :(得分:1)
您需要部分模板专业化,这是一个模板专业化,它本身又是一个模板。
使用函数模板是不可能的,但它与类有关。因此,解决方法是使用特化创建一个类模板(此处称为Magic
)。在该类中,调用一个简单的(非模板)函数。
然后,函数magic
转发到该类以隐藏&#34; hack&#34;:
Live demo of this code snippet
#include <iostream>
#include <vector>
#include <map>
// Forward declaration of the magic function:
template <typename> void magic();
// General case:
template <typename T>
struct Magic {
static void m(){
std::cout << "Called magic<T>" << std::endl;
}
};
// Vector case:
template <typename T>
struct Magic<std::vector<T> > {
static void m(){
std::cout << "Called magic<std::vector<T> >" << std::endl;
magic<T>();
}
};
// Map case:
template <typename T, typename U>
struct Magic<std::map<T,U> > {
static void m(){
std::cout << "Called magic<std::map<T> >" << std::endl;
magic<T>();
magic<U>();
}
};
// Implementation of the magic function:
template <typename T>
void magic() {
std::cout << "Forwarding..." << std::endl;
Magic<T>::m();
}
int main() {
magic<std::vector<std::map<std::string,std::vector<int> > > >();
}