C++ C++;:有没有办法从实例化模板中提取类型? //对STL容器执行操作的类模板 模板 结构foo{ T包含元素()的容器{ T-con; elee; con.推回(+++e); 返回con; }
如您所见,将元素的类型放入templates的参数中是非常愚蠢的,因为它已经包含在容器的类型中 那么,从T中得到元素的类型有什么魔力吗 大量Thx:-)标准库中的每个“容器”都试图遵守。这个概念要求,给定一个容器C++ C++;:有没有办法从实例化模板中提取类型? //对STL容器执行操作的类模板 模板 结构foo{ T包含元素()的容器{ T-con; elee; con.推回(+++e); 返回con; },c++,templates,C++,Templates,如您所见,将元素的类型放入templates的参数中是非常愚蠢的,因为它已经包含在容器的类型中 那么,从T中得到元素的类型有什么魔力吗 大量Thx:-)标准库中的每个“容器”都试图遵守。这个概念要求,给定一个容器T: T::value\u type是容器元素的类型 T::reference是容器元素的引用类型 T::const_reference是容器元素的常量引用类型 在特定示例中,可以通过以下方式提取元素类型: //a class template to do something to ST
T
:
T::value\u type
是容器元素的类型T::reference
是容器元素的引用类型T::const_reference
是容器元素的常量引用类型//a class template to do something to STL container
template<typename T/*should be a STL container*/,typename Ele/*the type of element*/>
struct foo{
T a_container_with_an_element(){
T con;
Ele e;
con.push_back(++++e);
return con;
}
模板
结构foo{
容器a_容器_与_元素(){
集装箱集装箱;
typename容器::值\类型e;
con.推回(+++e);
返回con;
}
如果容器是标准库容器,则元素的名称是容器的嵌入名称,如下所示:
template<typename Container>
struct foo {
Container a_container_with_an_element(){
Container con;
typename Container::value_type e;
con.push_back(++++e);
return con;
}
标准容器中有一些标准名称(例如,请参阅)和§23.2
如果
T
应该是STL容器,则可以使用模板模板参数。它必须是支持push_back()
的容器,并且我们将结合STL容器包含第二个“分配器”参数的事实
在这种情况下,你可以使用
X::value_type
X::reference
X::const_reference
X::iterator
X::const_iterator
X::difference_type
X::size_type
template
结构foo
{
类型DEF Con Con Con Con Con_类型;
类型定义元素值\u类型;
容器\键入带有元素()的容器\类型
{
集装箱式集装箱;
e型值;
con.push_back(e);//或先修改e,但不修改++++e
返回con;
}
};
你的代码就可以了
template< template<typename, typename> class Con,
typename Ele, typename Alloc = std::allocator<Ele> >
struct foo
{
typedef Con<Ele, Alloc> container_type;
typedef Ele value_type;
container_type a_container_with_an_element()
{
container_type con;
value_type e;
con.push_back( e ); // or modify e first but not ++++e
return con;
}
};
foomyfoo;
std::vector myvec=myfoo.a_容器_与_an_元素();
如果只需要一个模板参数
foo< std::vector, int > myfoo;
std::vector<int> myvec = myfoo.a_container_with_an_element();
模板
结构foo
{
typedef typename Con::value\u type value\u type;
将容器与元素()合并
{
康康;
e型值;
con.push_back(e);//或先修改e,但不修改++++e
返回con;
}
};
使用方法:
template< typename Con >
struct foo
{
typedef typename Con::value_type value_type;
Con a_container_with_an_element()
{
Con con;
value_type e;
con.push_back( e ); // or modify e first but not ++++e
return con;
}
};
foomyfoo;
std::vector myvec=myfoo.a_容器_与_an_元素();
请注意,在本例中,您还可以执行
foo::Ele
来获取元素类型。您也可以为容器类型创建typedef
。通常在模板中使用。(模板未完全限定时,您需要typename
。因此foo
是完全限定的,不需要它。在您知道t是STL容器的特殊情况下,如果Nall的答案正确,请使用容器中的嵌套类型
但是,如果您想要更通用的“我知道我得到的模板是T,我想要该模板的第一个参数的类型”案例,您可以通过模板专门化获得类型:
foo<std::vector<int> > myfoo;
std::vector<int> myvec = myfoo.a_container_with_an_element();
模板
结构MyFirstElement;
模板
结构MyFirstElement{
使用类型=T_类型;
};
//单元测试
使用MustBeInt=typename MyFirstElement::Type;
使用mustAlley=typename MyFirstElement::Type;
静态断言(std::is_same::value,“”);
静态断言(std::is_same::value,“”);
//即使它不是STL容器,也可以这样做
模板
结构MyCrazyContainer{};
静态断言(std::is_same::value,“”);
下面是一个活生生的例子:
正如Jarod42所指出的,这只适用于“常规”模板,即仅将类型作为参数。例如,std::array之所以这样做是因为它有一个int作为第二个参数。这取决于您想如何使用它。例如,您可以使用
typeid(…)
如果要将类型用作容器中的键,或typeid(…).name()
如果您想将其作为std:string。您的意思是像typedef typename T::value\u type type
这样的东西吗?我真的不推荐+++e
@Niall这样的答案。模板模板参数将不起作用。所有std
容器都至少有两个模板参数-元素类型和分配器。N还有一点要提的是,Ele
可能无论如何都不应该是模板参数。分配器总是可选的,所以我希望它能工作。虽然我为Ele键入了错误的内容。我以后必须检查我的解决方案是否编译。它不是那么通用的…它不适用于容器作为std::array
。您可以这样做尝试类似于std::remove_reference::type
@Jarod42是的,就像任何方法一样,它是有限的。正如我所说的,它并不是对OPs问题的真正答案,但它确实回答了一个毫无疑问许多人会在OPs问题标题下期待的问题。
foo<std::vector<int> > myfoo;
std::vector<int> myvec = myfoo.a_container_with_an_element();
template<typename T>
struct MyFirstElement;
template<template<typename...> class T_Container, typename T_Type, typename... Ts>
struct MyFirstElement<T_Container<T_Type,Ts...>>{
using Type = T_Type;
};
//unit test
using MustBeInt = typename MyFirstElement<std::vector<int>>::Type;
using MustBeLong = typename MyFirstElement<std::map<long,float>>::Type;
static_assert(std::is_same<MustBeInt,int>::value,"");
static_assert(std::is_same<MustBeLong,long>::value,"");
//this works too even though its not an STL container
template<typename T, typename U, typename Z>
struct MyCrazyContainer{};
static_assert(std::is_same<typename MyFirstElement<MyCrazyContainer<bool,long,float>>::Type,bool>::value,"");