我正在写一个模板类,并且我想允许仅针对特定模板类型存在其他方法。当前,该方法适用于所有模板类型,但会导致所有其他类型的编译错误。
复杂的是,这是一个重载的operator()。不知道我想要做什么实际上是否可以在这里进行。
这是我现在所拥有的:
template<typename T, typename BASE>
class MyClass : public BASE
{
public:
typename T& operator() (const Utility1<BASE>& foo);
typename T const& operator() (const Utility2<BASE>& foo) const;
};
我希望
T&
版本始终可用,但是T const&
版本仅在Utility2<BASE>
有效的情况下可用。目前,这两种方法都存在,但是如果Utility2<BASE>
无效,则尝试使用const版本会产生奇怪的编译错误。我宁愿有一个明智的错误,甚至是“没有这样的成员函数”错误。这可能吗?
编辑:阅读了boost文档后,这是我想到的,它似乎可以工作:
template<typename T, typename BASE>
class MyClass : public BASE
{
public:
typename T& operator() (const Utility1<BASE>& foo);
template<typename U>
typename boost::enable_if<boost::is_same<Utility2<BASE>, U>, T>::type const &
operator() (const U& foo) const;
};
因此,除非有人尝试将其与Utility2一起使用,否则该方法将不存在,并且仅当Utility2对于该BASE类型有效时,他们才能创建Utility2。但是,当对于该BASE类型无效时,MyClass不会浪费时间创建访问器方法。
最佳答案
是的,这是可能的,但不能直接与类模板参数一起使用。 boost::enable_if
只能与方法本身上的模板参数一起使用。因此,使用一点typedef用法:
template<typename T, typename BASE>
class MyClass : public BASE
{
public:
typedef Utility2<BASE> util;
typename T& operator() (const Utility1<BASE>& foo);
template<typename U>
typename boost::enable_if<boost::is_same<util, U>, T>::type const &
operator() (const U& foo) const;
};
之所以可行,是因为Utility2仅可以从特定的BASE类型创建。因此,如果BASE类型是其他类型,operator()的const版本将不存在。
因此,这是一件非常小的事情。它并没有给我带来多少好处。但这很整齐。