当T
为double(float)const
时,当我尝试使用function<T>
时出现此错误。
implicit instantiation of undefined template 'std::function<double (float) const>'
但T
为double(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的错误更加神秘,但基本相同)
答案 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) const
与R(ArgTypes...)
不匹配,因此您将获得未定义的基本模板。
如何修复此问题并删除const,以便将此函数类型放入
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;
}