从类'方法返回* this是一个很好的习惯,因此可以链接方法调用。考虑这个例子:
template <typename T> class container
{
public:
container& append(const T& x) {
...
return *this;
}
};
container<int> a;
a.append(1).append(2).append(5);
然而,当从这个派生出一个新类时,它会破坏链:
class int_container : public container<int>
{
public:
int_container& sort_ascending() {
...
return *this;
}
};
int_container b;
b.append(10).sort_ascending(); // error: container::sort_ascending() does not exist
这可以通过复制基类的方法并更新返回类型来解决......
class int_container : public container<int>
{
int_container& append(int i) { container<int>::append(i); return *this; }
...
};
...但是,我的基类有60个这样的方法,我需要几个派生类。那么,有没有办法在派生类中更新这些方法的返回类型,而不必覆盖每个派生类中的每个单个方法?并且不使用预处理器宏?
答案 0 :(得分:0)
以下是针对相关代码段的基于CRTP的解决方案:
#include <type_traits>
template <typename T, typename R>
struct container_return_type
{
typedef R& type;
};
template <typename T>
struct container_return_type<T, void>
{
typedef T& type;
};
template <typename T, typename R = void> class container
{
public:
typename container_return_type<container<T>, R>::type append(const T& x) {
return static_cast<typename container_return_type<container<T>, R>::type>(*this);
}
};
class int_container : public container<int, int_container>
{
public:
int_container& sort_ascending() {
return *this;
}
};
int main(int argc, char** argv)
{
int_container b;
b.append(10).sort_ascending();
container<double> c;
c.append(1.0).append(2.0);
return 0;
}
当然,您必须在每个要链接的方法中进行转换。