鉴于以下代码: -
#include <algorithm>
#include <iostream>
#include <functional>
#include <string>
void func(std::function<void(void)> param)
{
param();
}
void func(std::function<void(int)> param)
{
param(5);
}
int main(int argc, char* argv[])
{
func([] () { std::cout << "void(void)" << std::endl; });
func([] (int i) { std::cout << "void(int): " << i << std::endl; });
std::string line;
std::getline(std::cin, line);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
从VS2010编译错误: -
CppTest.cpp(18): error C2668: 'func' : ambiguous call to overloaded function
1> CppTest.cpp(11): could be 'void func(std::tr1::function<_Fty>)'
1> with
1> [
1> …Run Code Online (Sandbox Code Playgroud) 以下代码无法在GCC 4.7.2或Clang 3.2中编译:
#include <vector>
#include <functional>
int main()
{
std::vector<std::function<void()>> a;
std::vector<std::function<void()>> b{a};
}
Run Code Online (Sandbox Code Playgroud)
问题是编译器将尝试使用initializer_list创建b,显然它应该只是调用复制构造函数.然而,这似乎是期望的行为,因为标准表明initializer_list构造函数应该优先.
这段代码适用于其他std :: vector,但对于std :: function,编译器无法知道你是否需要initializer_list构造函数或其他构造函数.
它似乎没有办法解决它,如果是这种情况,那么你永远不能在模板化代码中使用统一初始化.这将是一个巨大的耻辱.
另一方面,Visual Studio(2012年11月CTP)并没有抱怨这一点.但是此时initializer_list支持不是很好,所以它可能是一个bug.
通用lambda可以利用"替换失败不是错误"规则吗?例
auto gL =
[](auto&& func, auto&& param1, auto&&... params)
-> enable_if_t< is_integral<
std::decay_t<decltype(param1)>
>::value>
{
// ...
};
auto gL =
[](auto&& func, auto&& param1, auto&&... params)
-> enable_if_t< !is_integral<
std::decay_t<decltype(param1)>
>::value>
{
// ...
};
Run Code Online (Sandbox Code Playgroud)
是否有任何变通方法或计划将其包含在语言中?此外,由于通用lambda是引擎盖下的模板化功能对象,这是不是有点奇怪,这是不能做到的?
假设我有一个可变高阶函数
template<typename F, typename ...Args>
void execution(F func, Args&&... args)
{
func(std::forward<Args>(args)...);
}
Run Code Online (Sandbox Code Playgroud)
然后为这个重载集
void f() {}
void f(int arg) {}
Run Code Online (Sandbox Code Playgroud)
过载分辨率是不可能的
int main()
{
execution(f, 1);
execution(f);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
然而,如果只提供两者中的任何一个,程序就会编译
如果我f()从套装中取出并更换它f(arg, arg2)仍然存在问题.有解决方法,还是我总是要提供函数的类型作为模板参数?
execution<void()>(f);
Run Code Online (Sandbox Code Playgroud)