我有以下类型特征:
template <class T>
struct Arity : Arity<decltype(&T::operator())> {};
template <class T, class R, class... Args>
struct Arity<R(T::*)(Args...)> {
static constexpr auto value = sizeof...(Args);
};
template <class T, class R, class... Args>
struct Arity<R(T::*)(Args...) const> {
static constexpr auto value = sizeof...(Args);
};
template <class R, class... Args>
struct Arity<R(*)(Args...)> {
static constexpr auto value = sizeof...(Args);
};
Run Code Online (Sandbox Code Playgroud)
对于大多数用例来说,找到函数所使用的参数数量非常有用,但是对于一个常见情况它会失败:
auto l1 = [](int, double){};
Arity<decltype(l1)>::value; // works, 2
auto l2 = [](auto, auto){};
Arity<decltype(l2)>::value; // error: Reference to overloaded …Run Code Online (Sandbox Code Playgroud) 我假设这是不可能的,因为我收到以下错误:
error C3533: 'auto': a parameter cannot have a type that contains 'auto'
Run Code Online (Sandbox Code Playgroud)
这是重现错误的代码片段:
int myInts[] = {1,2,3,3,3,4};
std::vector<int> myVec(myInts, myInts + sizeof(myInts)/sizeof(int));
myVec.erase(
std::remove_if(myVec.begin(), myVec.end(),
[](auto i){return i==3;}), // lambda param error
myVec.end());
Run Code Online (Sandbox Code Playgroud)
现在如果你要写这个而不是一切都很好,它会擦除值为3的元素:
int myInts[] = {1,2,3,3,3,4};
std::vector<int> myVec(myInts, myInts + sizeof(myInts)/sizeof(int));
myVec.erase(
std::remove_if(myVec.begin(), myVec.end(),
[](int i){return i==3;}),
myVec.end());
Run Code Online (Sandbox Code Playgroud)
那么你可以简单地不用auto作函数参数,因为错误暗示了吗?
这是因为类型auto是由rvalue决定的,编译器无法推断它尽管它是在已知向量上执行的算法的谓词int?
有谁知道原因?
我想知道标准委员会是否考虑扩展 C++14auto关键字来推断函数模板参数类型,因为它现在存在于泛型 lambda 中。(正如在这个答案中可以很好地描述的那样)
因为它适用于 lambda 函数,所以它也应该适用于任何函数。当然,使用经典语法将完全多余:
template< typename T >
void f(T param);
Run Code Online (Sandbox Code Playgroud)
但是能够写这个,以获得相同的结果:
void f(auto param);
Run Code Online (Sandbox Code Playgroud)
我认为可以减少阻塞的代码(更短更整洁),并在这个用例中实现很好的一致性:
auto v = func1();
f(v);
Run Code Online (Sandbox Code Playgroud)
如您所见,我们使用自动类型推导器来声明v,但随后我们必须使用硬类型参数化函数 f 或模板化函数 f。
结合auto我们应该使用auto,这将更加一致。
编辑:这个问题确实有效地提出了同样的问题,但不那么直接。并且还没有得到 user657267 给出的答案,我在其下复制和扩展。
这是我创建的代码片段:
auto f = [](auto a) -> auto {
cout << a << endl;
return a;
};
cout << f(12) << endl;
cout << f("test");
Run Code Online (Sandbox Code Playgroud)
这是我所知道的:类型必须在编译时全部解析/指定。
这里的问题是,当编译器看到这个 lambda 函数 f 时,它会如何表现?它如何推导出特定用途的所有类型,如第 6 行和第 7 行,我们可以看到每次调用 lambda 函数 f 时都会传递两个不同的参数。编译器是否创建 lambda 函数 f 的不同实例来匹配传递的类型?
任何帮助将不胜感激!
另外,如果答案技术性太强,无法用几行代码写出来,我将不胜感激有关 lambda 函数及其工作原理的任何良好参考。
我注意到的一件事是,以通常的方式定义函数时不允许使用 auto:
void f(auto a)
{
}
Run Code Online (Sandbox Code Playgroud)
这不能编译。
我知道泛型lambda,我知道变量模板,但是,这有什么作用?它甚至被允许了吗?
template<typename T>
auto f = [](auto a, T b){ /**/ };
Run Code Online (Sandbox Code Playgroud)
如果允许,可以按预期使用吗?那就是f<type>(var_a, var_b)?
我有一个基本语法问题。我试图理解在赋值中使用方括号内的运算符的含义。例如
a = [&] (const std::string&) { ... };
a = [=] (const std::string& b) { ... };
谢谢,