如何使用“使用”功能?例如
class A;
void f(int);
struct B
{
using BA = A;
using Bf = f; ???
};
答案 0 :(得分:11)
你可以做到
struct B
{
using BA = A;
constexpr static auto Bf = f;
}
这样你就不用担心指定类型,这可能很烦人。
您不希望声明非静态变量,否则对象的每个副本都将携带一个函数指针。你也不希望它是可变的,因为那样你就可以重新分配它。您也不希望它在运行时可能被确定,因为编译器必须在给定的上下文中证明对Bf
的调用实际上是在调用f
,否则付费函数间接成本。 constexpr
处理最后两点。
答案 1 :(得分:2)
如果f
只是一个函数,你可以添加一个成员函数指针:
void (*Bf)(int) = f;
或只是将其包装在一个函数中:
void Bf(int i) { f(i); }
可能更喜欢后者,因为它避免了向B
添加额外成员。
如果f
是一个功能模板,则不能只是别名,您需要转发它:
template <class... Args>
auto Bf(Args&&... args)
-> decltype(::f(std::forward<Args>(args)...))
noexcept(noexcept(::f(std::forward<Args>(args...))))
{
return ::f(std::forward<Args>(args)...);
}
这是......是的。
答案 2 :(得分:2)
Nir Friedman's answer很棒,但如果f
超载,它就无法工作。
在C ++ 14中,您可以使用a generic lambda:
获得解决方案struct B {
using BA = A;
static constexpr auto BF = [](auto&&... args) {
return f(std::forward<decltype(args)>(args)...);
};
};
如果这看起来有点复杂,那只是因为std::forward
的冗长。我将在没有std::forward
的情况下显示它,以便更容易掌握(但不要使用它,因为如果f
引用类型为params,它将会失败):
struct B {
using BA = A;
static constexpr auto BF = [](auto... args) { return f(args...); };
};
答案 3 :(得分:0)
区别在于A
只是一种类型而f
是实际函数。如果您想使用using
将Bf
定义为f
的类型,请使用:
using Bf = decltype(f);