我一直在考虑为我的 C++ 项目编写 static_if ,我偶然发现了以下代码:
#include <iostream>
using namespace std;
namespace static_if_detail {
struct identity {
template<typename T>
T operator()(T&& x) const {
return std::forward<T>(x);
}
};
template<bool Cond>
struct statement {
template<typename F>
void then(const F& f){
f(identity());
}
template<typename F>
void else_(const F&){}
};
template<>
struct statement<false> {
template<typename F>
void then(const F&){}
template<typename F>
void else_(const F& f){
f(identity());
}
};
} //end of namespace static_if_detail
template<bool Cond, typename F>
static_if_detail::statement<Cond> static_if(F const& f){
static_if_detail::statement<Cond> if_;
if_.then(f);
return if_;
}
template<typename T>
void decrement_kindof(T& value){
static_if<std::is_same<std::string, T>::value>([&](auto f){
f(value).pop_back();
}).else_([&](auto f){
--f(value);
});
}
int main() {
// your code goes here
std::string myString{"Hello world"};
decrement_kindof(myString);
std::cout << myString << std::endl;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
这对我来说都是有意义的,除了一件事struct identity:. 它接受 T 类型的 rhs,称为 x、cool 等等。但是当identity被调用时,实际上没有任何东西传递到身份中。
template<typename F>
void then(const F& f){
f(identity());
}
Run Code Online (Sandbox Code Playgroud)
上面,f 调用identity,但没有将任何内容传递给identity。然而,identity 返回转发的参数(在我的例子中,是一个 std::string),并弹出字符串的最后一个字符。当身份本身没有传递给它来转发的参数时,它如何返回转发的参数?
f不调用identity-f使用 的实例调用identity。浏览一下这里的两个案例:
static_if<std::is_same<std::string, T>::value>([&](auto f){
f(value).pop_back();
}).else_([&](auto f){
--f(value);
});
Run Code Online (Sandbox Code Playgroud)
如果T是std::string,那么我们实例化 a statement<true>,它then()用 的实例调用传入的函数identity。第一个 lambda 的参数f是 类型identity- 所以实际上是 ,我们f(value)确实是。valuevalue.pop_back()
如果T不是std::string,那么我们实例化一个不执行任何操作statement<false>的对象then(),并使用 的else_()实例调用 lambda identity。再次f(value)是正义value和我们所做的--value。
这是一个非常令人困惑的实现static_if,因为f在 lambda 中始终是一个identity。这是有必要的,因为我们不能value直接使用(不能写value.pop_back(),因为那里没有依赖名称,所以编译器会很高兴地确定它对于整数来说格式不正确),所以我们只是将所有使用包装value在一个依赖函数中对象延迟该实例化(f(value)取决于f,因此在提供之前无法实例化f- 如果不调用该函数则不会发生)。
最好实现它,以便将参数实际传递给 lambda。
| 归档时间: |
|
| 查看次数: |
270 次 |
| 最近记录: |