gpt4 book ai didi

c++ - 各种集合的模板类偏特化

转载 作者:行者123 更新时间:2023-11-28 05:47:24 29 4
gpt4 key购买 nike

我正在尝试编写 2 个模板部分特化,它们应该以不同的方式处理序列容器和关联容器的序列化,但似乎序列容器特化根本没有被使用,因为编译器试图用错误的特化来特化它, 这是代码:

template<typename W, typename T, template<typename...> class C, typename... Args>
class Archiver<W, C<T, Args...>>
{
public:
template<typename U = C<T, Args...>, typename std::enable_if<std::is_same<typename U::value_type, T>::value, int>::type = 0>
static void serialize(const W& w, const C<T, Args...>& container)
{
...
}

template<typename U = T, typename std::enable_if<!std::is_base_of<archive::require_placement_move, U>::value, int>::type = 0,
typename J = C<T,Args...>, typename std::enable_if<std::is_same<typename J::value_type, T>::value, int>::type = 0>
static void unserialize(const W& r, const Context& c, C<T,Args...>& container)
{
...
}

template<typename U = T, typename std::enable_if<std::is_base_of<archive::require_placement_move, U>::value, int>::type = 0,
typename J = C<T,Args...>, typename std::enable_if<std::is_same<typename J::value_type, T>::value, int>::type = 0>
static void unserialize(const W& r, const Context& c, C<T,Args...>& container)
{
...
}
};

template< typename W, typename K, typename T, template<typename...> class M, typename... Args>
class Archiver<W, M<K, T, Args...>>
{
public:
template<class U = M<K,T,Args...>, typename std::enable_if<std::is_same<typename U::key_type, K>::value && std::is_same<typename U::mapped_type, T>::value, int>::type = 0>
static void serialize(const W& w, const M<K,T,Args...>& container)
{
...
}

template<class U = M<K,T,Args...>, typename std::enable_if<std::is_same<typename U::key_type, K>::value && std::is_same<typename U::mapped_type, T>::value, int>::type = 0>
static void unserialize(const W& r, const Context& c, M<K,T,Args...>& container)
{
...
}
};

如果我尝试使用

Writer w;
Archiver<Writer, std::list<float>>::serialize(...);

决议是在第二个特化上完成的,因此导致了

Candidate template ignored: substitution failure [with U = std::__1::list<float, std::__1::allocator<float> >]: no type named 'key_type' in 'std::__1::list<float, std::__1::allocator<float> >'

这应该意味着第一个特化被先验地排除,就像演绎决议选择与 map 相关的特化一样。或者,也许我遗漏了一些非常愚蠢的东西,因为我从一段时间以来一直在处理这段代码。

最佳答案

我认为您对 SFINAE 的使用有点不对。

您在 Archive 中明确指定了容器类型模板。一些未知的 C++ 规则意味着当您通过 std::list<float> 时选择第二个特化. SFINAE 然后应用于 serialize函数,消除唯一可用的重载(因此出现错误消息)。因为二专Archive已被选中,serialize 甚至从未考虑过第一个特化中的函数。这不是您想要的。

由于您明确指定了容器类型,我不确定您为什么要尝试使用 SFINAE。要分别专门针对序列容器和关联容器,您可能必须等到概念标准化。在那之前,你可以做一些天真的事情,比如根据类型别名 key_type 的存在进行专门化(这就是您已经在做的事情)。

这是一个例子:

#include <type_traits>

template<typename>
using void_t = void;

template<typename T, typename = void>
struct has_key_type : std::false_type
{
};

template<typename T>
struct has_key_type<T, void_t<typename T::key_type>> : std::true_type
{
};

template<typename C, typename = std::enable_if_t<has_key_type<C>::value>>
void serialize(C const& c)
{
};

template<typename C, typename = std::enable_if_t<!has_key_type<C>::value>, typename = void>
void serialize(C const& c)
{
};

#include <iostream>
#include <list>
#include <map>

int main()
{
serialize(std::list<int>());
serialize(std::map<float, float>());
}

关于c++ - 各种集合的模板类偏特化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35959639/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com