【发布时间】:2021-08-28 11:11:15
【问题描述】:
我有一个可调用的结构 Foo 定义为
struct Foo {
template <typename T>
void operator()(T i) const { /* ... */ }
};
出于超出范围的原因,我想静态选择要调用它的类型,避免使用以下繁琐的符号:
Foo foo;
foo.operator()<int>(0);
foo.operator()<char>('0');
foo.operator()<char>(0); // Notice: I want to select the implementation
// so that **implicit conversions may take place**.
为此,我想实现一个模板成员函数To(),这样上面就可以改写为:
foo.To<int>()(0);
foo.To<char>()('0');
foo.To<char>()(0);
基本上,foo.To<T>() 将返回一个可用作回调的可调用对象。
一种方法可以通过使用 lambdas 来完成:
struct Foo {
template <typename T>
void operator()(T i) const { /* ... */ }
template <typename T>
auto To() const {
return [this](T i) -> void {
return this->operator()<T>(i);
};
}
};
但是,我不太喜欢这种解决方案,因为它会创建一个 lambda 并按值返回它,而我更希望有某种Foo 的“静态转换”没有计算开销与对成员函数的简单调用相比。也可以采用 CRTP 解决方案,但它可能会添加太多样板代码,而我希望这样做会更简单。 实现上述目标最有效的方法是什么?
【问题讨论】:
-
您如何确定存在计算开销?我相当有信心任何非无脑编译器都会优化它。
-
另外,不漂亮,但
foo.operator()<char>(0);有效。 -
编译器会为你做这个优化,不用费心。
-
另外,为什么不干脆做
foo.To<int>(0);并完全跳过lambda?您是否打算在实际代码中调用它之前存储 lambda 并传递它? -
@Frank @super 您是否声称 lambda 解决方案与普通函数调用一样高效? lambda解决方案至少没有额外的间接层吗?我应该存储 lambda 并通过
const引用返回它吗?
标签: c++ templates functor crtp callable-object