2012-12-04 79 views
19

(我将这个问题限制在C++ 11中,因为我相信在C++ 98中没有这样做的一般方法)。在C++中重命名(别名/转发)函数的最佳方式是什么?

假设我有一个复杂的(在签名计算)设置模板功能和/或重载函数,我想以完全相同的方式来使用这些功能,但使用不同的名称(即别名)。

例如:

template<class A, class B, class C> 
D fun(A a, B& b, C&& c){ ... } 

template<class E, class F> 
G fun(H<E> he, F& f){ ... } 

... many other versions of fun 

现在假设我想重命名(或别名,或更精确)这些功能,都在一次(即能够使用同一个功能的不同名称,而不用重写它)。这样,在代码的其他部分,我可以使用不同的名称并且不需要修改上面的代码。

这是正确的方式重命名(别名/转发)fun转换成gun

template<typename... Args> 
inline auto gun(Args&&... args)->decltype(fun(std::forward<Args>(args)...)){ 
    return fun(std::forward<Args>(args)...); 
} 
  • 难道真的有什么看法?
  • 这是最简单的方法吗?
  • 这是最佳方式吗? (例如可以内联,没有不必要的副本)
  • 如果原始函数具有一些SFINAE功能,该怎么办? (例如template<class A, class B, class C, class = std::enable_if<...>::type>),decltype会在所有情况下转移SFINAE吗?
  • 如果原始函数返回引用该怎么办?是不是decltype去除引用类型? (例如double& fun(double& x){return x;})。
  • 关于成员函数可以这么说吗?

澄清:gun永远不会是正好fun,因为实例将有不同的地址,但我在找的是对的观点通用编码的点的重命名。我发现奇怪的是,几乎所有的东西都可以被重命名/转发,命名空间,类型(typedef)和模板类型using typedef,但不是函数(或关于成员函数)。


编辑:为了完整,而且由于这似乎是这样做的方式,在这里我添加了一个宏来定义函数别名:

#define ALIAS_FUNCTION(OriginalnamE, AliasnamE) \ 
template <typename... Args> \ 
inline auto AliasnamE(Args&&... args) -> decltype(OriginalnamE(std::forward<Args>(args)...)) { \ 
    return OriginalnamE(std::forward<Args>(args)...); \ 
} 

,然后你使用它像这样:

namespace NS1{namepsace NS2{ 
    ALIAS_FUNCTION(NSA::fun, gun); // second argument (target name can't have namespace) 
}} 
+2

我认为这很好。 'decltype'获得正确的类型(即'&'用于返回左值引用的函数,'&&'用于返回右值引用的函数,否则为非引用)。 –

+7

拜托,如果你描述你实际在做什么,你会让每个人都变得更加轻松。你不重命名*任何*。原来的名字仍然存在。您正在转发,或提供别名或包装函数。这与重命名没有任何关系。重命名意味着*更改*名称,使旧名称消失,转而使用新名称 – jalf

+0

@jalf,好点。我想,让原来的名字消失很难。我想象的唯一方法是将原始定义放入一个未命名的名称空间中。但是,是的,这不是主意。 – alfC

回答

10

难道真的有什么看法?

是的。

这是最简单的方法吗?

是的(遗憾的是)。

这是最佳方式吗? (例如可以内联,没有不必要的副本)

是的。

如果原始函数具有一些SFINAE功能会怎么样? (例如template<class A, class B, class C, class = std::enable_if<...>::type>),在所有情况下都会decltype转移SFINAE?

是的,如果内部decltype表达产生错误(即,fun不存在,这可能是由于SFINAE上fun),这将触发SFINAE为gun藏汉,从过载集合移除它。

如果原始函数返回引用会怎样?是不是decltype去除引用类型? (例如double& fun(double& x){return x;})。

不,为什么呢?

对于成员函数可以这么说,尽管这样做必须修改我猜的类。

这不是问题。关于会员功能可以说些什么?以上所有内容同样适用。

+1

+1为“可悲”。由于我没有收到否定答案,我会将其标记为已接受。 – alfC

相关问题