trait从成员函数类型中删除const?

Aar*_*aid 9 c++ templates const

Tdouble(float)const我得到这个错误,当我尝试使用function<T>.

implicit instantiation of undefined template 'std::function<double (float) const>'
Run Code Online (Sandbox Code Playgroud)

但是什么时候T可以double(float).我试图用它std:: remove_cv<T>::type来删除它const,但这不起作用.是的,我有#include<functional>.

所以我的主要问题是:如何修复此问题并删除,const以便我可以将此函数类型放入std:: function.


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


但我的第二个问题是:double(float)const甚至意味着什么?!! 我能够了解

double (ClassName::) (float) const
Run Code Online (Sandbox Code Playgroud)

因为这意味着成员函数无法修改其ClassName对象.当我将此类型放入模板中以删除类类型时,我得到的double(float)const是导致问题的.

template<typename>
struct DropClassType;
template<typename Sig, typename C>
struct DropClassType<Sig (C::*)> {
  typedef Sig type_without_class;
};
Run Code Online (Sandbox Code Playgroud)

(clang 3.4.2.来自g ++ - 4.9.1的错误更加神秘,但基本相同)

T.C*_*.C. 10

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

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

template<class> class function; // undefined
template<class R, class... ArgTypes>
class function<R(ArgTypes...)>  { /* ... */ };
Run Code Online (Sandbox Code Playgroud)

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


如何解决这个问题并删除co​​nst以便我可以将此函数类型放入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...); };
Run Code Online (Sandbox Code Playgroud)

当然,类似的技巧可用于删除ref-qualifiers.


是什么double (float) const,甚至什么意思?!

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

具有cv-qualifier-seqref-qualifier(包括由typedef-name(7.1.3,14.1)命名的类型)的函数类型应仅显示为:

  • 非静态成员函数的函数类型,
  • 指向成员的指针引用的函数类型,
  • 函数typedef声明或别名声明的顶级函数类型,
  • type-parameter(14.1)的默认参数中的type-id,或
  • 类型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
Run Code Online (Sandbox Code Playgroud)

- 结束例子 ]

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


Pio*_*cki 6

#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;
}
Run Code Online (Sandbox Code Playgroud)

现场演示链接.