【问题标题】:Removing qualifiers with partial template instantiation使用部分模板实例化删除限定符
【发布时间】:2018-09-04 17:23:20
【问题描述】:

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

例如

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&amp;,当[T_data_type] = const T_data_type&amp; 的形式时我遇到了问题。例如,在函数add() 中,这将扩展为add(const const T_data_type&amp;&amp; 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 在用户代码中用作好吧;可能将未解析的类型传入add(),这也是未解析的,因此编译器无法为调用找到匹配的函数。

编辑:

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

感谢您的回答。

【问题讨论】:

  • 类定义末尾的分号在哪里?

标签: c++ templates c++98


【解决方案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);
};

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-09-06
    相关资源
    最近更新 更多