要实现带有回调函数和参数的接口,
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
指示符,只需删除&
。
谢谢您的回答。
答案 0 :(得分:1)
该标准已经为您提供了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);
};
要在较旧的编译器中同时使用这两种方法,您可以只复制“可能的实现”部分中的内容-但是,我确实建议您更新到较新的编译器(如果有的话)。