是否可以在可变参数模板中推断出容器类型
Can the container type be deduced in variadic templates?
In C++11/C++14,
template <
typename T ,
template <typename...> class Container_t
>
void MyFunc(Container_t<T> &data) { ... }
template <typename T>
void MyFunc2( T v ) { ... }
int main()
{
std::vector<char> v;
MyFunc<char, std::vector>(v); // OK
MyFunc(v); // error
int i;
MyFunc2<int>(i); // OK
MyFunc2(i); // OK
}
我收到MyFunc(v)
错误.
是否有可能以任何方式让编译器找出传递给可变参数模板函数的容器的类型?我认为找出它没有问题,就像普通模板中的普通类型一样。
如果我需要更改 v 的类型,我是否必须修复对 MyFunc 的所有调用?
编译器:Microsoft Visual C++ 2015 (v140)
与其尝试推断容器类型,不如假设容器定义了它存储的类型。
template <typename Container>
void MyFunc(Container& data)
{
// all std containers defines value_type member (also reference etc.)
using std::begin;
using value_type = typename Container::value_type;
value_type value = *begin(data);
...
}
请注意,您可能根本不需要存储元素的类型:
template <typename Container>
void MyFunc(Container& data)
{
using std::begin;
auto value = *begin(data);
...
}
如果您只想处理 std 容器(或具有类似模板参数的容器) - 请参阅 Richard Hodges 的答案。
诀窍是命名模板的模板参数:
#include <vector>
#include <iostream>
#include <typeinfo>
template <
typename T ,
typename A,
template <typename = T, typename = A> class Container_t
>
void MyFunc(Container_t<T, A> &data) {
std::cout << "value type = " << typeid(T).name() << std::endl;
std::cout << "allocator type = " << typeid(A).name() << std::endl;
std::cout << "container type = " << typeid(Container_t<T,A>).name() << std::endl;
}
template <typename T>
void MyFunc2( T v ) { }
int main()
{
std::vector<char> v;
MyFunc<char, std::allocator<char>, std::vector>(v); // OK
MyFunc(v); // now ok
}
如果您不关心除值类型和容器之外的任何东西......
#include <vector>
#include <map>
#include <iostream>
#include <typeinfo>
template <
typename T ,
typename...Rest,
template <typename, typename...> class Container_t
>
void MyFunc(Container_t<T, Rest...> &data) {
std::cout << "value type = " << typeid(T).name() << std::endl;
std::cout << "container type = " << typeid(Container_t<T,Rest...>).name() << std::endl;
}
template <typename T>
void MyFunc2( T v ) { }
int main()
{
std::vector<char> v;
std::map<char, int> m;
// MyFunc<char, std::allocator<char>, std::vector>(v); // OK
MyFunc(v); // now ok
MyFunc(m); // now ok
}
我的猜测是这是一个VC ++错误,因为GCC和CLANG可以推断出输入模板参数。正如KerrekSB在评论中提出的那样,一个不那么痛苦的解决方法如下:
template<typename T, template<typename...> class Container_t, typename... Args>
void MyFunc(Container_t<T, Args...> &data) {
...
}
现场演示
相关文章:
- "auto"推断出 hashtable_policy.h 中的错误类型
- 三元运算符 '?:' 在 4.9.0 之前的 GCC 版本中推断出不正确的类型?
- 为什么"return (str);"推断出与C++中的"return str;"不同的类型?
- 为什么编译器不能从返回类型中推断出模板参数?
- 从第一类型的第二个非类型参数中推断出第一类
- 是否可以推断出模板功能中的参数类型
- std::forward 如何推断出"_Ty"的类型?
- 如何允许编译器推断出正确的返回类型以进行模板get函数
- 自动无法推断出正确的返回类型
- 既然C++知道类型,它能推断出点和箭头吗?
- 如何使模板化运算符推断出正确的返回类型
- 编译器无法推断出要返回的模板类型
- 是否可以推断出 std::insert_iterator 的包含类型
- 是否可以在可变参数模板中推断出容器类型
- 为什么unique_ptr无法推断出删除程序的类型?
- 错误:调用"反向"没有匹配函数:候选模板被忽略:推断出参数的冲突类型
- 汽车推断出的那种类型是什么?
- 哪些 IDE 和文本编辑器可以推断出在 C++11 中使用 auto 关键字声明的变量类型
- 是否可以推断出左值引用非类型模板参数
- 无法推断出嵌套类型的模板函数