gpt4 book ai didi

c++ - 不同类型的模板函数

转载 作者:行者123 更新时间:2023-11-27 23:46:34 25 4
gpt4 key购买 nike

我怎样才能制作一个至少适用于任何类型,枚举,std::vector<T> , std::vector<E>对于枚举 E

我使用重载解析和 enable_if 尝试了以下操作, 但它适用于 intvector<int> , 它失败了 vector<E>说它找不到要调用的函数:

struct Details
{
template<typename T>
typename std::enable_if<std::is_enum<T>::value, T>::type
get_impl(const std::string& key, T*) const
{
return static_cast<T>(get_impl<int>(key, static_cast<int*>(0)));
}

template<typename T>
int get_impl(const std::string& key, int*) const
{
return int();
}

template<typename T>
typename std::enable_if<std::is_enum<T>::value, std::vector<T>>::type
get_impl(const std::string& key, std::vector<T>*) const
{
return std::vector<T>();
}


template<typename T>
std::vector<int> get_impl(const std::string& key, std::vector<int>*) const
{
return T();
}

template<typename T>
T getValue(const std::string& key)
{
return get_impl<T>(key, static_cast<T*>(0));
}
};

int main()
{
enum E {A, B};
Details details;
details.getValue<int>(""); // ok
details.getValue<std::vector<int>>(""); // ok
details.getValue<std::vector<E>>(""); // error: no matching function
}

我有一个特殊的重载 vector<enum> , 为什么它不起作用?

最佳答案

你的问题是你没有保持你的类型直截了当,你在混合和匹配提供显式类型和进行模板推导。如果您非常仔细地查看收到的错误消息,就会明白发生了什么。

在枚举情况下,您正在调用:

details.getValue<std::vector<E>>("");

调用:

template<typename T>
T getValue(const std::string& key)
{
return get_impl<T>(key, static_cast<T*>(0));
}

在这里,Tstd::vector<E> .到目前为止,一切都很好。现在,您要调用的重载是:

template<typename T>
typename std::enable_if<std::is_enum<T>::value, std::vector<T>>::type
get_impl(const std::string& key, std::vector<T>*) const

但您称它为 get_impl<T>(...) .这意味着,在尝试解决此过载时,Tstd::vector<E>最后一个参数是 std::vector<std::vector<E>>* .所以这个函数模板根本不是候选者——最后一个参数不匹配,即使匹配,std::vector<E>不是枚举,所以 enable_if会排除它。


修复它的方法是将所有东西都保留在演绎世界中。当我们在那里时,避免使用空指针进行标记分派(dispatch)。这很令人困惑 - 因为现在您的代码的某些部分使用指针作为指针,而有些只是将它们用作类型。我们可以创建一个特殊类型作为类型使用:

template <typename T> struct tag { };

然后传入:

template <typename T>
T getValue(std::string const& key ) {
return get_impl(key, tag<T>{});
}

请注意,我不再为 get_impl 指定类型,就会推导出来。现在,您的枚举案例是:

template<typename T>
typename std::enable_if<std::is_enum<T>::value, std::vector<T>>::type
get_impl(const std::string& key, tag<std::vector<T>>) const

这会奏效。我们可以推断出 T作为E来自 tag参数,就像您最初想要的那样,以及 E是一个枚举,所以这有效。

请注意,即使您使用的是 C++11,别名模板也可以使用。因此,虽然您无权访问 std::enable_if_t ,你仍然可以写:

namespace xstd {
template <bool B, typename T>
using enable_if_t = typename std::enable_if<B, T>::type;
}

这使得所有这些东西更容易阅读:

template<typename T>
xstd::enable_if_t<std::is_enum<T>::value, std::vector<T>>
get_impl(const std::string& key, tag<std::vector<T>>) const

关于c++ - 不同类型的模板函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50088707/

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