使用部分模板实例化删除限定符

时间:2018-09-04 17:23:20

标签: c++ templates c++98

要实现带有回调函数和参数的接口,

Ex。

template<class T_class_type, class T_data_type>
class Some_interface
{
public:
  Some_interface(T_class_type* inst, void (T_class_type::*func)(T_data_type));
  void add(const T_data_type& data);
private:
  void call(const T_data_type& data);
};

其中T_data_type可以是任何类型,并且具有限定符const&,当形式为[T_data_type] = const T_data_type&时我遇到问题。例如,在函数add()中,它将扩展为add(const const T_data_type&& data)。明显的编译器错误。我们之所以采用常量引用,是为了减少不必要的数据复制。无论如何,为了解决这个问题,我实现了以下内容,

template<class T_data_type>
struct No_qualifiers
{
  typedef T_data_type Type;
};

template<class T_data_type>
struct No_qualifiers<T_data_type&>
{
  typedef T_data_type Type;
};

template<class T_data_type>
struct No_qualifiers<const T_data_type>
{
  typedef T_data_type Type;
};

template<class T_data_type>
struct No_qualifiers<const T_data_type&>
{
  typedef T_data_type Type;
};

template<class T_class_type, class T_data_type>
class Some_interface
{
public:
  Some_interface(T_class_type* inst, void (T_class_type::*func)(T_data_type));
  void add(const typename No_qualifiers<T_data_type>::Type& data);
private:
  void call(const T_data_type& data);
};

我的测试中的部分专业化消除了接口用户可能错误地传递给template参数的不必要的限定符。

在实践中使用此方法,我发现了我无法完全解释的错误。我希望能有新的一双眼睛可以看到这种方法的警告。

我遇到的一些情况是我无法更改用户调用界面的方式,并且我使用的是2003年以前的标准。我认为,我目前正在调试的错误源于用户使用的typename代码也;可能会将未解析的类型传递到add()中,该类型也无法解析,因此编译器无法找到该调用的匹配函数。

编辑:

因此,我遇到的“类型名”问题是与该问题无关的编码错误。另外,我发现不需要删除const指示符,只需删除&

谢谢您的回答。

1 个答案:

答案 0 :(得分:1)

该标准已经为您提供了std::remove_referencestd::remove_const所要实现的功能; typedef可提高可读性:

class SomeInterface
{
    using ArgType
        = typename std::remove_const<std::remove_reference<T>::type>::type;
    void add(ArgType const& data);
};

要在较旧的编译器中同时使用这两种方法,您可以只复制“可能的实现”部分中的内容-但是,我确实建议您更新到较新的编译器(如果有的话)。