假设,我想开发一个通用库,它应该可以使用类似数字的类型,包括双重和用户定义的类型。我现在面临的问题是,我不知道如何编写函数模板的返回类型,就像这样:
template<class T>
auto transmogrify(T x)
-> ???
{
using std::abs;
return abs(x)+2.0;
}
using声明使这个函数模板的主体适用于原始类型,因为它们没有关联的命名空间(因此没有ADL)。但是我希望transmogrify使用专门的abs函数,以防用户定义类型的作者提供自己的abs函数。我不能简单地使用
-> decltype( abs(x)+2.0 )
因为这不适用于比赛,因为std :: abs不在范围内(据我所知)。但是写作
-> decltype( std::abs(x)+2.0 )
会禁用ADL。但禁用ADL不是一种选择。此外,专业abs函数返回的值可能不是T类型,而是其他类型。
关于如何解决返回类型问题的任何想法,同时(a)保持ADL和(b)回退到某些默认函数(例如在这种情况下为std :: abs),不提供专门的类型绝对
答案 0 :(得分:12)
使用单独的命名空间,您可以在其中放置using子句。这可以防止命名空间污染,因为using子句仅适用于该命名空间。我建议将它命名为独特的东西,这样你就不会意外地将它传播开来。
namespace transmog_detail
{
using std::abs;
template<class T>
auto transmogrify(T x) -> decltype(abs(x) + 2.0)
{
return abs(x) + 2.0;
}
}
// Then pull it into the current namespace, as recommended by @LucDanton.
using transmog_detail::transmogrify;
// Or if there is a reason, you can forward.
// template<class T>
// auto transmogrify(T x)
// -> decltype(transmog_detail::transmogrify(x))
// {
// return transmog_detail::transmogrify(x);
// }
答案 1 :(得分:-6)
上面的答案很好,但我能想到的最简单的方法是使用typeinfo标题。它专门用于确定对象的类型和构造函数。
见这里:http://www.cplusplus.com/reference/std/typeinfo/type_info/