C++ 尝试创建"中间"函子
C++ Trying to create an 'Intermediate' functor
我所说的"中间"函子的意思是:一个普通的函子,其中一个参数可以在调用时指定。 问题是我有一个动画时间轴(本质上是特定帧的标量值),并且它的输出需要通过管道传输到要动画的对象中的 getter/setter 方法。 这是我正在尝试的简化示例:
template < class ObjType, class Getter, class Setter, typename Scalar >
class Sy_propertyBridge : public Sy_abstractPropertyBridge
{
public:
Sy_propertyBridge( ObjType* object, Getter getter,
Setter setter )
: obj_( object ), get_( getter ),
set_( setter ) {}
virtual ~Sy_propertyBridge() {}
inline virtual float get() const
{
// Cannot handle default arguments.
Scalar tmp = ( obj_->*get_ )();
return static_cast< float >( tmp );
}
inline virtual void set( float value )
{
Scalar tmp = static_cast< Scalar >( value );
( obj_->*set_ )( tmp );
}
private:
ObjType* obj_;
Getter get_;
Setter set_;
};
时间轴只包含浮点数,因此无论对象用于其 getter/setter 方法的标量类型,都必须进行强制转换(我对浮点数进行了部分专门化,取消了强制转换)。 ObjType
是动画对象类型,Getter
和Setter
是指向方法的指针,Scalar
是 Getter 和 Setter 类型,需要处理。
我认为这很好,但是编译失败了,因为一些getter/setter具有其他默认初始化的参数。 我不认为这会是一个问题,因为它们是默认的! 但是当编译器期望指针指向方法的参数比我提供的更多时,它失败了。
然后,我尝试使用可变参数模板参数,以便可以手动输入默认值,但在第一个障碍处失败了,因为我无法将参数包存储为成员以作为参数重复应用于指针指向方法。 我也一直在查看 std::function 和 std::bind,我希望能够使用 getter/setter 方法的默认 args 预设将 std::function 存储为成员 - 并在调用之前从时间线更改适当的参数。 只是我找不到办法...
有人对实现我的目标有任何建议吗? 还是我的设计从根本上存在缺陷,并且有更简单的方法?
std::function
将是要走的路。只会使用 std::function<Scalar(const ObjType*)>
作为你的 getter,std::function<void(ObjType*, Scalar)>
作为你的二传手(如果 Scalar
s 可以隐式转换为 float
s,我什至会使用 std::function<float(ObjType const*)>
和 std::function<void(ObjType*, float)>
,或者)。您可以初始化这些,例如。使用λ函数:
Sy_propertyBridge(my_obj,
[](const MyObjType* o) -> float { return o->opacity; },
[](const MyObjType* o, float f) { o->opacity=f; })
请注意,可能有更优雅的方法可以做到这一点(例如,可能只有一个函数可以同时用作 getter 和 setter)。
更进一步,您可以
- 摆脱
obj_
成员变量 - 摆脱函数的
o
参数
然后,lambda 必须记住它们将对其进行操作的对象。所以上面的构造函数调用将变为
Sy_propertyBridge(
[]() -> float { return my_obj->opacity; },
[](float f) { my_obj->opacity=f; })
据我了解,您正在尝试使用"获取"和"设置"方法,这些方法因您在此处传递的类而异? 如果是这样,我认为您应该尝试在"ObjType"对象上使用纯虚拟基类,然后在要传入的类中实现它。 在 C#/Java 术语中,这指的是接口。
基本上是这样的:
class IGetSetter
{
virtual float get() const = 0;
virtual void set(float) = 0;
}
class ObjType1 : public IGetSetter
{
virtual float get() const
{
// Implementation
}
virtual void set(float a)
{
// Implementation
}
}
class ObjType2 : public IGetSetter
{
virtual float get() const
{
// Implementation
}
virtual void set(float a)
{
// Implementation
}
}
然后你的类变成:
template < typename Scalar >
class Sy_propertyBridge : public Sy_abstractPropertyBridge
{
public:
Sy_propertyBridge( IGetSetter* object)
: obj_( object ) {}
virtual ~Sy_propertyBridge() {}
inline virtual float get() const
{
Scalar tmp = obj_->get(); // Uses polymorphism to find the right method
return static_cast< float >( tmp );
}
}
inline virtual void set( float value )
{
Scalar tmp = static_cast< Scalar >( value );
obj_->set( tmp ); // Uses polymorphism to find the right method
}
private:
ObjType* obj_;
};
但实际上,可能有一种直接的方法可以完全取消您的Sy_propertyBridge类。 只需存储指向IGetSetter
的指针数组,然后在它们执行所需操作时直接调用它们。
- () 函子后面的括号,而不是函数指针?
- 将方法转换为调用该方法的成员函子对象会导致崩溃
- C++函子,有什么有效的方法吗?
- 在 C++11 中获取函子作为参数
- 为什么我不能返回带有透明函子的法线映射引用?
- C++函子以防止重复?
- C++:对函子重载调用运算符的未定义引用
- 隐式转换为比较函数对象(函子)用于 std::sort 而不是 std::map?
- C++模板函数中,指定回调函子/lambda 的参数类型,同时仍允许内联?
- 函子还有更有用的用例吗?
- 完美转发C++重载和模板化函子及其参数
- 有没有办法从同一类中的函子调用类方法?
- std::bind() 参数列表中函子的执行顺序(可能与函数参数的求值顺序无关)
- 将函子传递到模板化函数中
- C++函子作为函数的输出参数
- 让线程拥有它C++运行的函子
- IDE 认为函子是构造函数?
- C++区分函子和值模板参数
- qsort 比较函子的分段错误
- C++ 尝试创建"中间"函子