我正在尝试编写一个float(float)函数类
#pragma once
class float_func
{
struct concept
{
virtual ~concept() {}
virtual float operator()(float) = 0;
virtual concept* clone() = 0;
};
template <typename T>
class impl : public concept
{
public:
impl(const T& ptr) : ptr_(ptr) {};
virtual float operator()(float arg1) {
return ptr_(arg1);
}
virtual concept* clone() {
return new impl<T>(ptr_);
}
private:
T ptr_;
};
public:
float_func() { object_ = nullptr; }
template <typename T> float_func(const T& ptr) : object_(new impl<T>(ptr)) {}
float_func(const float_func& other) : object_(other.object_->clone()) {}
~float_func() { delete object_; }
template <typename T>
float_func& operator=(const T& ptr) {
delete object_;
object_ = new impl<T>(ptr);
return *this;
}
float_func& operator=(const float_func& other) {
delete object_;
object_ = other.object_->clone();
return *this;
}
float operator()(float arg1) {
return (*object_)(arg1);
}
private:
concept* object_;
};
尝试使用它:
#include <iostream>
#include <functional>
#include "float_func.h"
struct FloatFunctor
{
float operator()(float a) {
return a * 2.f;
}
};
float mul3(float a) {
return a * 3.f;
}
int main()
{
float_func f1 = FloatFunctor();
float_func f2 = &mul3;
//float_func f3 = mul3; //! does not compile
std::function<float(float)> sf = mul3;
std::function<float(float)> sf2 = &mul3;
std::cout << f1(1) << " " << f2(2) << " " << sf(3) << " " << sf2(4) << std::endl;
return 0;
};
float_func f3 = mul3
不会编译,但stl版本会编译。
错误信息:
float_func.cc
C:\Program Files (x86)\Microsoft Visual Studio 11.0\VC\INCLUDE\xlocale(336) : wa
rning C4530: C++ exception handler used, but unwind semantics are not enabled. S
pecify /EHsc
e:\src\tmp\type_erasure\float_func.h(14) : warning C4180: qualifier applied to f
unction type has no meaning; ignored
e:\src\tmp\type_erasure\float_func.h(28) : see reference to class templa
te instantiation 'float_func::impl<T>' being compiled
with
[
T=float (float)
]
float_func.cc(20) : see reference to function template instantiation 'fl
oat_func::float_func<float(float)>(T (__cdecl &))' being compiled
with
[
T=float (float)
]
e:\src\tmp\type_erasure\float_func.h(22) : error C2207: 'float_func::impl<T>::pt
r_' : a member of a class template cannot acquire a function type
您能解释一下错误吗?
std :: function如何处理这种模板参数,或者如何修改我的代码以支持float_func f3 = mul3
?
该表达式mul3
具有函数类型:,float(float)
而不是函数指针类型(如float (*)(float)
)。因此,float_func
推导的ctor模板就是T
这个函数类型float(float)
:
template <typename T> float_func(const T& ptr)
替换后:
float_func(float (&ptr)(float)) // T = float(float)
这导致实例化impl<float(float)>
又试图声明此函数类型(T ptr_
)的成员-但这是非法的[temp.arg.type] / 3:
如果声明通过依赖于模板参数的类型获取函数类型,并且这导致声明不使用函数声明符的句法形式具有函数类型,则程序格式错误。[示例:
template<class T> struct A { static T t; }; typedef int function(); A<function> a; // ill-formed: would declare A<function>::t // as a static member function
—结束示例]
我能想到的最简单的解决方案是按值接收接收器参数:
template <typename T> float_func(T ptr)
这为函数类型的表达式推导了函数指针类型(强制函数到指针的转换)。
另一种方法是impl
使用衰减实例化T
,例如new impl< typename std::decay<T>::type >(ptr)
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句