我想编写一个将进程应用于类成员的函数.以下代码正在运行:
class AA
{
public:
AA(){};
~AA(){};
std::string type="AA";
};
class BB
{
public:
BB(){};
~BB(){};
template <typename T, typename TT>
void test(T& a, TT(T::*memberPtr))
{
std::cout<<"test: "<<(a.*memberPtr)<<std::endl;
}
std::string type="BB";
};
int main()
{
AA a;
BB b;
b.test(a, &AA::type);
}
Run Code Online (Sandbox Code Playgroud)
但是我在编译时知道所有内容所以我想知道是否有可能写一些等价但只有模板?所以我可以这样写:
b.test<&AA::type>(a);
Run Code Online (Sandbox Code Playgroud)
调用内部测试(a):
std::cout<<"test: "<< (a.*MEMBER) <<std::endl; // MEMBER is given in template
Run Code Online (Sandbox Code Playgroud)
或类似的东西.
采取以下示例,该示例取自cplusplus.com参考页,并更改为return false:
// find_if example
#include <iostream> // std::cout
#include <algorithm> // std::find_if
#include <vector> // std::vector
bool IsOdd (int i) {
return ((i%2)==1);
}
int main ()
{
std::vector<int> myvector;
myvector.push_back(10);
myvector.push_back(20);
myvector.push_back(40);
myvector.push_back(50);
std::vector<int>::iterator it = std::find_if (myvector.begin(), myvector.end(), IsOdd);
std::cout << "The first odd value is " << *it << '\n';
return 0;
}
Run Code Online (Sandbox Code Playgroud)
由于in myvector中的值都不是奇数,因此它将返回InputIterator last,它是未定义的:
The first odd value is -1727673935
Run Code Online (Sandbox Code Playgroud)
处理此输出的正确方法是什么?
我如何知道std::find_if()返回false的结果是否是不可预测的,并且与整个向量进行比较以确认结果值不存在,从而挫败了 …
我想知道我的编译器使用以下代码做了什么
void design_grid::design_valid()
{
auto valid_idx = [this]() {
if ((row_num < 0) || (col_num < 0))
{
return false;
}
if ((row_num >= this->num_rows) || (col_num >= this->num_rows))
{
return false;
}
return true;
}
/* some code that calls lambda function valid_idx() */
}
Run Code Online (Sandbox Code Playgroud)
如果我反复调用上面的(design_grid::design_valid)成员函数函数,那么当我的程序遇到valid_idx每次创建时会发生什么?编译器是否在编译时内联后面调用的代码,以便在valid_idx遇到创建时实际上不执行任何操作?
UPDATE
汇编代码的一部分如下.如果这有点太多了,我会稍后发布另一批有色的代码,以说明哪些部分是哪些.(目前没有一种很好的方法可以与我对代码段进行着色).还要注意我已经更新了我的成员函数的定义和上面的lambda函数,以反映它在我的代码中真正命名的内容(因此,在汇编语言中).
在任何情况下,似乎lambda都是与main函数分开定义的.lambda函数由_ZZN11design_grid12design_validEvENKUliiE_clEii下面的函数表示.反过来,在函数的正下方,外部函数(design_grid::design_valid)由_ZN11design_grid12design_validEv开始表示.稍后_ZN11design_grid12design_validEv,打电话给_ZZN11design_grid12design_validEvENKUliiE_clEii.进行调用的这一行看起来像
call _ZZN11design_grid12design_validEvENKUliiE_clEii #
Run Code Online (Sandbox Code Playgroud)
如果我错了,请纠正我,但这意味着编译器将lambda定义为函数外的正常design_valid函数,然后将其作为正常函数调用它应该是什么时候?也就是说,每次遇到声明lambda函数的语句时,它都不会创建新对象?我在该特定位置看到lambda函数的唯一迹线是# tmp85, valid_idx.__this在第二个函数中注释的行,就在函数开始时重新调整的基本和堆栈指针之后,但这只是一个简单的movq操作.
.type _ZZN11design_grid12design_validEvENKUliiE_clEii, …Run Code Online (Sandbox Code Playgroud) 我的问题是扩展这个:为什么lambdas可以通过编译器比普通函数更好地优化?
重申一下,结论是lambdas创建了不同的特化,编译器可以简单地内联,而函数指针不像内联那么容易,因为对于一组函数原型只有一个特化.考虑到这一点,将函数指针模板作为快速/更快的lambdas?
int add(int a, int b) { return a + b; }
int sub(int a, int b) { return a - b; }
template <class F>
int operate(int a, int b, F func)
{
return func(a, b);
}
template <int func(int, int)>
int operateFuncTemplate(int a, int b)
{
return func(a, b);
}
int main()
{
// hard to inline (can't determine statically if operate's f is add or sub since its just a function pointer)
auto addWithFuncP = …Run Code Online (Sandbox Code Playgroud)