取消专门化C++模板参数
Un-specializing C++ template parameter
基本上我想做的事情如下。假设我们有一个模板成员函数foo:
template <typename T>
T SomeClass::foo();
并且不知何故,用户通过了map<string,int>作为模板参数:
foo<map<string, int>>();
这里我想做的是,在定义函数foo时,获取内部类型,string和int。我试了很多猜测来解释这个论点,但都无济于事。
template <map<typename K, typename V>>
map<K, V> SomeClass::foo(); // absolutely illegal
我曾想过使用部分专门化,但它没有起作用,因为foo是一个类成员函数。
如果您想要从模板中获取内部类型的通用方法,可以使用显式专门化:
template <typename T>
struct unpack;
template <template <typename...> class C, typename A, typename B>
struct unpack<C<A, B>>
{
using first = A;
using second = B;
};
用法:
static_assert(std::is_same_v<string,
typename unpack<map<string, int>>::first
>);
static_assert(std::is_same_v<int,
typename unpack<map<string, int>>::second
>);
如果你只关心在调用函数时这样做,你可以把函数做成一个模板:
template <typename K, typename V>
void foo(std::map<K, V>);
即兴:
template< class T >
struct Foo
{
static auto impl() -> T;
};
template< class K, class V >
struct Foo< map< K, V > >
{
static auto impl() -> map< K, V >;
};
template< class T >
auto foo()
-> T
{ return Foo<T>::impl(); }
这里有另一个可能的解决方案。方法foo分派给一个foo_detail方法,该方法将指向T的指针作为参数。foo_detail中未使用该参数。相反,该参数允许重载解析选择调用哪个foo_detail。
由于未使用的参数,该解决方案有一种笨拙的感觉。幸运的是,这可以隐藏在SomeClass的私有部分,这样SomeClass用户就不必知道它了
#include <map>
#include <iostream>
#include <string>
#include <typeinfo>
using std::map;
using std::cout;
using std::endl;
using std::string;
class SomeClass
{
public:
template <typename T>
T foo()
{
return foo_detail((T *)0);
}
private:
template<typename T>
T foo_detail(T *)
{
cout << "foo called with type " << typeid(T).name() << endl;
return T();
}
template <typename K, typename V>
map<K, V> foo_detail(map<K, V> *)
{
cout << "foo map specialization called with types "
<< typeid(K).name() << ' ' << typeid(V).name() << endl;
return map<K,V>();
}
};
int main()
{
SomeClass s;
s.foo<double>();
s.foo<map<int, string> >();
return 0;
}
相关文章:
- 如何反转整数参数包
- 使用C++库在Android项目中修改gradle中的cmake参数,用于插入指令的测试
- 如何使用默认参数等选择模板专业化
- 模板参数替换失败,并且未完成隐式转换
- 具有默认模板参数的多态类的模板推导失败
- lambda参数转换为constexpr技巧,然后获取带链接的数组
- 将数组作为参数传递给函数安全吗?作为第三方职能部门,可以探索他们想要的之外的其他元素
- 函数调用中参数的顺序重要吗
- 部分定义/别名模板模板参数
- 模板-模板参数推导:三个不同的编译器三种不同的行为
- 使用不带参数的函数访问结构元素
- 基于另一个成员参数将函数调用从类传递给它的一个成员
- 如何在OMNET++中指定与命令行参数组合的输出文件名
- 如何使用Luacneneneba API正确读取字符串和表参数
- 在派生函数中指定void*参数
- 视图中的参数推导失败:take_while
- static_assert在宏中,但也可以扩展到可以用作函数参数的东西
- 使用指向成员的指针将成员函数作为参数传递
- 没有名称的C++模板参数
- 如何将enable-if与模板参数和参数包一起使用