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

时间:2014-09-03 21:47:26

标签: c++ templates const

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

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

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

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

2 个答案:

答案 0 :(得分:10)

  

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

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...)不匹配,因此您将获得未定义的基本模板。


  

如何修复此问题并删除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...); };

当然,类似的技巧可以用来删除 ref-qualifiers


  

double (float) const甚至意味着什么?!!

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

  

具有 cv-qualifier-seq ref-qualifier 的函数类型(包括   由 typedef-name (7.1.3,14.1)命名的类型仅出现在:

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

- 结束示例]

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

答案 1 :(得分: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;
}

Live demo link.