Ale*_*son 5 c++ lambda gcc templates c++11
假设我有一个标题wrapper.h:
template <typename Func> void wrapper(const Func func);
Run Code Online (Sandbox Code Playgroud)
和一个文件wrapper.cpp包含:
#include "wrapper.h"
template <typename Func>
void wrapper(const Func func)
{
func();
}
Run Code Online (Sandbox Code Playgroud)
并且文件main.cpp包含:
#include "wrapper.h"
#include <iostream>
int main()
{
wrapper( [](){std::cout<<"hello."<<std::endl;} );
}
Run Code Online (Sandbox Code Playgroud)
如果我一起编译这些(例如cat wrapper.cpp main.cpp | g++ -std=c++11 -o main -x c++ -),我没有链接器错误.
但是如果我单独编译它们(例如g++ -std=c++11 -o wrapper.o -c wrapper.cpp && g++ -std=c++11 -o main main.cpp wrapper.o),我当然---得到一个链接器错误:
Undefined symbols for architecture x86_64:
"void wrapper<main::$_0>(main::$_0)", referenced from:
_main in main-5f3a90.o
Run Code Online (Sandbox Code Playgroud)
通常,我可以明确地专门化wrapper并添加这样的东西wrapper.cpp:
template void wrapper<void(*)()>(void(*)())
Run Code Online (Sandbox Code Playgroud)
但是这种特殊的模板专业化不起作用.
是否可以在lambda上专门化模板?
首先,我假设你知道为什么模板只能在头文件中实现?
对于你的问题:
是否可以在lambda上专门化模板?
不幸的是,模板专业化与精确匹配一起使用,而a lambda是一种唯一的未命名类型.问题是专门针对您不知道的那种类型.
你最好的选择是使用std::function; 或者像你一样,然后通过添加强制lambda转换为函数指针+
int main()
{
wrapper(+[](){std::cout<<"hello."<<std::endl;} );
}
Run Code Online (Sandbox Code Playgroud)
完整示例:
#include <iostream>
template <typename Func>
void wrapper(const Func func)
{
std::cout << "PRIMARY\n";
func();
}
template <>
void wrapper<void(*)()>(void(*func)())
{
std::cout << "SPECIALIZATION\n";
func();
}
int main()
{
wrapper([](){std::cout<<"hello\n"<<std::endl;} );
wrapper(+[](){std::cout<<"world."<<std::endl;} );
}
Run Code Online (Sandbox Code Playgroud)
这将打印
PRIMARY
hello
SPECIALIZATION
world
Run Code Online (Sandbox Code Playgroud)
此外,decltype设施无济于事,如果确实如此,它将带走您对lambda的需求的灵活性
| 归档时间: |
|
| 查看次数: |
572 次 |
| 最近记录: |