C++ 部分模板专业化的意外结果
在使用我的个人格式库时,我遇到了一些意想不到的结果。我已经将代码简化为您可以在下面或上面找到的列表C++ 部分模板专业化的意外结果,c++,templates,c++11,template-specialization,C++,Templates,C++11,Template Specialization,在使用我的个人格式库时,我遇到了一些意想不到的结果。我已经将代码简化为您可以在下面或上面找到的列表 #包括 #包括 #包括 #包括 模板 结构执行器{ 内联静态void exec(const T&){ std::cout将可变模板代码更改为以下内容: template <template <typename ...> class Container, typename ... Ts> struct executioner<Container<Ts ...&
#包括
#包括
#包括
#包括
模板
结构执行器{
内联静态void exec(const T&){
std::cout将可变模板代码更改为以下内容:
template <template <typename ...> class Container,
typename ... Ts>
struct executioner<Container<Ts ...> > {
inline static void exec(const Container<Ts ...> & c){
std::cout << "cont" << std::endl;
auto it = c.begin();
executioner<typename Container<Ts...>::value_type>::exec(*it);
}
};
如果使用上面的代码运行replacement,您将看到conditionalstd::is_samefirst),const int>:value
为true
。这意味着*它的类型是std::pair
,而不是std::pair
。因此,您的专门化“失败”.包含类型的typedef不是std::pair
。它是const std::pair&
。这就是您的第一个部分专门化不匹配的原因。您可以这样修改它:
template <typename T1, typename T2>
struct executioner<const std::pair<T1, T2>&> {
inline static void exec( const std::pair<T1, T2> & t ) {
std::cout << "pair" << std::endl;
executioner<T1>::exec( t.first );
executioner<T2>::exec( t.second );
}
};
在后一种情况下,ContainedType
是std::pair
,正如预期的那样()。好的,现在我想起来了:)
正如所暗示的那样,您可以使用std::remove_reference
删除引用。我还删除了const
限定符(请参阅)。我的便利结构如下所示:
template <typename T>
struct to_value
{
typedef typename std::remove_const<
typename std::remove_reference< T >::type
>::type type;
};
typedef decltype( *it ) ContainedType;
executioner< typename to_value<ContainedType>::type >::exec( *it );
模板
结构到_值
{
typedef typename std::remove_const<
typename std::remove_reference::type
>::类型类型;
};
你这样称呼它:
template <typename T>
struct to_value
{
typedef typename std::remove_const<
typename std::remove_reference< T >::type
>::type type;
};
typedef decltype( *it ) ContainedType;
executioner< typename to_value<ContainedType>::type >::exec( *it );
typedef decltype(*it)包含类型;
刽子手::exec(*it);
现在您只需要专门处理值类型。这里是。您的代码专门处理std::pair
而不是std::map
@402,但是ContainedType
是std::pair
或者至少应该是。因此,我假设嵌套调用executioner::exece(*it);
转到专门用于std::pair
的函数。对于ContainedType
可以尝试Container::value\u type
的ContainedType
加分:为什么这不适用于decltype(*it)
?@elemakil*它
是对pair的类型引用(const std::pair&/code>)它与您的泛型常量T&
-case匹配。@elemakil:您专门处理对
,但*它是对常量&
@elemakil,然后是valueof typeid()。名称依赖于实现。它不是真正的类型。请查看一个修改过的。我认为这是您所希望的std::remove\u reference
是合理的。
typedef decltype( *it ) ContainedType;
executioner< typename to_value<ContainedType>::type >::exec( *it );