【发布时间】:2012-11-27 23:15:57
【问题描述】:
我有以下smart_ptr 类。
template <typename T>
class smart_ptr
{
public:
// ... removed other member functions for simplicity
T* get() { return ptr; }
template <typename... Args>
decltype(T::template operator ()(Args()...)) operator ()(Args... args) const
{
return (*get()).operator ()(args...);
}
private:
T* ptr;
};
但是,当我将 smart_ptr 类用于没有 operator () 的类型 T 时,它无法编译(这是正确的)。
我想要的是只有当 T 有operator () 时才使用std::enable_if 来启用成员函数。当我开始这样做时,它变得非常模糊和复杂,因为我正在考虑使用 SFINAE 来检测 T 是否有operator (),然后将它与std::enable_if 结合起来得到我想要的。但是,我在创建 SFINAE 时迷失了方向,该 SFINAE 能够检测 一个以 operator () 为模板的可变参数(即 不是Is it possible to write a template to check for a function's existence? 的副本)。
有人可以帮忙吗?或者给出另一个(也许更简单的)解决方案?
附言它必须在 GCC 4.5.3 上工作。
编辑:为了完整起见,我已经用 GCC 4.5.3 的有效解决方案回答了我自己的问题。
【问题讨论】:
-
具体来说,检查my answer,它显示了如何使用尾随返回类型轻松完成:
auto operator()(Args... args) -> decltype((*get())(args...)){ ... }。不过,问题是:为什么限制为operator()?如果T定义了一个函数指针的转换,你可以得到所谓的surrogate call functions,虽然它们可能不常见,但最好是通用的(而且看起来更整洁)。 -
Xeo:它是如何复制的?这是一个带有可变参数模板的函数,而不是几年前我已经知道的直接函数!
-
'它无法编译(而且是正确的)'。嗯,编译器不应该将类模板成员的实例化推迟到它们被使用的地步吗?这意味着它应该不会编译失败,除非您实际上尝试使用
operator()或您以某种方式强制完成模板实例化? -
@Zach:嗯,你确实知道 4.5 通常不支持可变参数模板,对吧?有什么原因不能更新编译器?
-
@Xeo:这个问题明确针对 GCC 4.5.3。如果它不可能,那么回答并说不可能。
标签: c++ templates gcc c++11 sfinae