2

我有以下代码可以正常工作:

template<typename T>
class Base {
    virtual void call(T) = 0;
};

class Derived : public Base<int> {
    void call(int);
}

template<typename T>
void registerBase(const Base<T>& ref) {}

这种方法可以在调用 as 时T自动检测类型。当我切换到:intregisterBase(Derived())shared_ptr

template<typename T, typename Q>
void registerBase(shared_ptr<Q> ptr) {
    static_assert(is_base_of<Base<T>, Q>::value, "Have to supply a type extending Base<...>");
}

我可以防止非法类型,但我似乎无法自动检测类型T。我可以使用一些技巧来自动将 shared_ptr 向下转换为Base<T>模板推导工作吗?还是有另一种方法可以找到 typename T

PS:万一Q扩展乘法Base<T>我想出错(自动推演应该失败)。

4

1 回答 1

1

可能有无数种方法可以做到这一点。这是一个:

template<class T>
T helper(const Base<T> &); // not defined

template<class Q> 
using base_param = decltype(helper(std::declval<Q>())); 

在实际代码中,您可能想要放入helper命名details空间(并且可能还要更改名称)。

如果您遇到T无法返回的类型(例如数组类型)的奇怪情况,这将中断。helper通过将' 的返回类型更改为,例如,identity<T>然后也相应地更改 的定义,它很容易修复base_param

于 2014-12-03T12:24:02.397 回答