gpt4 book ai didi

c++ - 使用 SFINAE 根据函数的特定重载是否存在来选择函数

转载 作者:IT老高 更新时间:2023-10-28 21:45:18 28 4
gpt4 key购买 nike

我一直在尝试根据是否过载 operator<<(std::ostream&, const T&) 在两个模板化函数之间进行选择存在。

例子:

template <typename T, typename std::enable_if</* ? */, int>::type = 0>
std::string stringify(const T& t)
{
std::stringstream ss;
ss << t;
return ss.str();
}

template <typename T, typename std::enable_if</* ? */, int>::type = 0>
std::string stringify(const T& t)
{
return "No overload of operator<<";
}

struct Foo { };

int main()
{
std::cout << stringify(11) << std::endl;
std::cout << stringify(Foo{}) << std::endl;
}

这可能吗?如果是这样,您将如何解决这个问题?

最佳答案

不需要enable_if ,当 operator<< 时,使用表达式 SFINAE 选择正确的重载存在。

namespace detail
{
template<typename T>
auto stringify(std::stringstream& ss, T const& t, bool)
-> decltype(ss << t, void(), std::string{})
{
ss << t;
return ss.str();
}

template<typename T>
auto stringify(std::stringstream&, T const&, int)
-> std::string
{
return "No overload of operator<<";
}
}

template <typename T>
std::string stringify(const T& t)
{
std::stringstream ss;
return detail::stringify(ss, t, true);
}

Live demo

stringify函数模板只是委托(delegate)给 detail::stringify 之一功能模板。然后,如果表达式 ss << t 则选择第一个。格式良好。未命名的bool参数用于消除两个 detail::stringify 之间的歧义。实现。由于主要stringify函数通过 true作为 detail::stringify 的参数,当 operator<< 时,第一个将是更好的匹配。存在过载。否则将选择第二个。

这个表达式decltype(ss << t, void(), std::string{})在第一个 stringify 的尾随返回类型中模板可能值得更详细的解释。这里我们有一个由逗号分隔的 3 个子表达式组成的表达式。

第一个,ss << t是什么决定了该函数模板是否通过模板参数替换并将其添加到重载决议集中。如果表达式格式正确,即如果所讨论的类型重载 operator<<,则会发生这种情况。 .

中间的子表达式,void()除了确保某些用户定义的 operator, 之外,不做任何事情。未选中(因为您无法使用 operator, 参数类型重载 void)。

第三个也是最右边的子表达式 std::string{}是什么决定了 detail::stringify 的返回类型功能。

关于c++ - 使用 SFINAE 根据函数的特定重载是否存在来选择函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23987925/

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