trait从成员函数类型中删除常量

trait to drop const from a member function type?

本文关键字:删除 常量 类型 函数 成员 trait      更新时间:2023-10-16

Tdouble(float)const时,我在尝试使用function<T>时会出现此错误。

implicit instantiation of undefined template 'std::function<double (float) const>'

但当Tdouble(float)时,这是可以的。我尝试使用std:: remove_cv<T>::type来删除此const,但这不起作用。是的,我有#include<functional>

所以我的主要问题是:如何修复这个问题并删除const,这样我就可以将这个函数类型放入std:: function中。?


我在使用lambdas的operator()方法时遇到了这个问题,但我认为这个问题通常是关于任何方法类型的,而不仅仅是针对lambdas


但我的第二个问题是:double(float)const到底是什么意思?!!我能理解

double (ClassName::) (float) const

因为这意味着成员函数不能修改其CCD_ 13对象。当我将此类型放入模板中以删除类类型时,我会得到导致问题的double(float)const

template<typename>
struct DropClassType;
template<typename Sig, typename C>
struct DropClassType<Sig (C::*)> {
  typedef Sig type_without_class;
};

(叮当3.4.2。g++-4.9.1中的错误更为隐蔽,但基本相同)

为什么我会得到"未定义模板的隐式实例化"错误?

std::function被定义为未定义的基本模板和与"正常"函数类型匹配的部分专门化(§20.9.11.2[func.wrap.func]):

template<class> class function; // undefined
template<class R, class... ArgTypes>
class function<R(ArgTypes...)>  { /* ... */ };

double (float) constR(ArgTypes...)不匹配,因此您将获得未定义的基本模板。


如何修复此问题并删除常量,以便将此函数类型放入std::function

标准的部分专业化技巧。在进行此操作的同时,让我们删除volatile

template<class> class rm_func_cv; // undefined
template<class R, class... ArgTypes>
class rm_func_cv<R(ArgTypes...)>  { using type = R(ArgTypes...); };
template<class R, class... ArgTypes>
class rm_func_cv<R(ArgTypes...) const>  { using type = R(ArgTypes...); };
template<class R, class... ArgTypes>
class rm_func_cv<R(ArgTypes...) volatile>  { using type = R(ArgTypes...); };
template<class R, class... ArgTypes>
class rm_func_cv<R(ArgTypes...) const volatile>  { using type = R(ArgTypes...); };

当然,类似的技巧也可以用于删除ref限定符


double (float) const到底是什么意思?!!

这是标准的一个相当模糊的角落(§8.3.5[dcl.fct]/p6):

带有cv限定符seqref限定符的函数类型(包括由typedef名称(7.1.3,14.1)命名的类型)只能显示为:

  • 非静态成员函数的函数类型
  • 指向成员的指针所指的函数类型
  • 函数typedef声明或别名声明的顶级函数类型
  • 类型参数的默认参数中的type id(14.1),或
  • 模板参数类型id(14.3.1)

示例

    typedef int FIC(int) const;
    FIC f; // ill-formed: does not declare a member function
    struct S {
      FIC f; // OK
    };
    FIC S::*pm = &S::f; // OK

--结束示例]

简而言之,它基本上是"半个类型",可以用来声明类成员函数或指向成员类型的指针(或作为模板参数传递)。

#include <functional>
template <typename T>
struct function_remove_const;
template <typename R, typename... Args>
struct function_remove_const<R(Args...)>
{
    using type = R(Args...);
};
template <typename R, typename... Args>
struct function_remove_const<R(Args...)const>
{
    using type = R(Args...);
};
int main()
{
    std::function<function_remove_const<double(float)const>::type> f;
}

实时演示链接。