首页 > 解决方案 > 使用部分模板实例化删除限定符

问题描述

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

前任。

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);
};

whereT_data_type可以是任何类型并且有限定符constand &,当 is 的形式时我有问题[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);
};

我的测试中的部分专业化删除了界面用户可能错误地传递给模板参数的不需要的限定符。

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

我遇到的一些情况是我无法更改用户调用接口的方式,并且我使用的是 2003 年以来的旧标准。我相信我目前正在调试的错误也源于typename用户代码中的使用;可能传入未解析的类型 into add(),这也是未解析的,因此编译器无法找到调用的匹配函数。

编辑:

所以我遇到的“类型名”问题是与问题无关的编码错误。此外,我发现删除说明const符是不必要的,只有&需要删除的。

谢谢你的回答。

标签: c++templatesc++98

解决方案


该标准已经为您提供了您自己尝试实现的std::remove_reference内容std::remove_const;typedef 提高了可读性:

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

要将两者与旧编译器一起使用,您可能只需从“可能的实现”部分复制 - 但是,我真的建议您更新到较新的编译器(当然,如果可用)。


推荐阅读