将铸造/施工转化为一种完美的可向前推进的功能
Turn casting / construction into a perfect forwardable function
SSCCE:
#include <functional>
using std::function;
using std::forward;
template<typename ToType, typename... FromTypes>
ToType construct(FromTypes&&... fromTypes) {
return ToType(forward<FromTypes>(fromTypes)...);
}
class Maybe {
public:
Maybe() : m_value(42.0f) {}
template<typename Function>
auto apply(Function function) const -> decltype(function(std::declval<float>())) {
return function(value());
}
private:
float const& value() const {
return m_value;
}
float m_value;
};
int main() {
Maybe a;
a.apply(construct<int, float>);
return 0;
}
给出错误:
test.cpp: In instantiation of ‘decltype (function(declval<float>())) Maybe::apply(Function) const [with Function = int (*)(float&&); decltype (function(declval<float>())) = int]’:
test.cpp:31:32: required from here
test.cpp:17:28: error: invalid initialization of reference of type ‘float&&’ from expression of type ‘const float’
return function(value());
^
从错误消息来看,value()
返回const&
这一事实显然是个问题。
这里的关键点是,类型不是在第17行推导出来的,值是在那里传递给它的。当construct
函数在第31行传递给apply
时,类型被赋值。
我为construct
的模板指定了错误的类型。construct<int, float>
。如果我使用construct<int, float const&>
,它的功能就很好。
然而,这是繁琐的,并且需要了解apply
的实现。它也永远不会绑定左值,因为T
和T&&
是不同的类型。(因为缺少类型推导。(
有没有一种方法可以让一个函数传递给另一个函数,并在调用它的站点上进行类型推导,这样我就可以让调用方或多或少透明地进行完美的转发?或者有没有另一种方法可以实现这一目的,而不会向调用者泄露复杂性?
这个怎么样?
#include <functional>
using std::function;
using std::forward;
template<typename ToType>
class construct
{
public:
template<typename... FromTypes>
ToType operator()(FromTypes&&... fromTypes) {
return ToType(forward<FromTypes>(fromTypes)...);
}
};
class Maybe {
public:
Maybe() : m_value(42.0f) {}
template<typename Function>
auto apply(Function function) const -> decltype(function(std::declval<float>())) {
return function(value());
}
private:
float const& value() const {
return m_value;
}
float m_value;
};
int main() {
Maybe a;
a.apply(construct<int>());
return 0;
}
您只需要指定要转换为的类型,在您给定的上下文中显然无法推导出该类型。
相关文章:
- 有符号的int和int-有没有一种方法可以在C++中区分它们
- 有一个打印语句的函数是一种糟糕的编程实践吗
- 有没有一种方法可以创建一个带有哈希表的数据库,该哈希表具有恒定时间查找功能
- 有没有一种方法可以在编译时获得作用域类名
- 对于C++中使用智能指针的指针算术限制,有没有一种变通方法
- 一种在C++中读取TXT配置文件的简单方法
- 有没有一种方法可以测量c++程序的运行时内存使用情况
- 有没有一种方法可以使用placement new将堆叠对象分配给分配的内存
- 在调用接收数组的方法时,模板化数组大小是不是一种糟糕的做法
- 有没有一种方法可以通过"typedef"为重新定义的基本类型定义特征和强制转换运算符
- 有没有一种"cleaner"的方法可以在指向基的指针向量中找到派生类的第一个实例?
- 有没有一种代码密度较低的方法来使用非默认构造函数初始化数组?
- 将错误返回给调用方而不是立即在 C++ 中抛出错误是否是一种好的做法
- 在 c++ 中,有一种方法可以创建一个包含地图作为值的树状地图?
- 有没有一种优雅而快速的方法来测试整数中的 1 位是否位于连续区域
- 在运行时检查继承是否只有一种类型和 void*
- C++ STD 函数运算符:有没有一种方法可以通过函数将一个向量映射到另一个向量上?
- 找到一种有效的方法,在 2 个巨大的缓冲区上执行 MAX,每字节字节
- 寻找一种更好的方法来表示无符号字符数组
- 将铸造/施工转化为一种完美的可向前推进的功能