假设我有以下功能
Dal.Person.GetAllByAge<T>(int iAge, Expression<Func<Person, T>> OrderBy)
Run Code Online (Sandbox Code Playgroud)
我想为表达式传递一个默认参数,如 OrderBy = e=>e.ID,
以便如果未定义此参数,则默认值是按 id 排序。
这怎么可能?
这不是有效的C++ 14吗?
auto f = [](auto x, auto y = std::decay_t<decltype(x)>{}) { };
f(0);
Run Code Online (Sandbox Code Playgroud)
我期待它大致相当于
auto f = [](int x, int y) { };
f(0, int{});
Run Code Online (Sandbox Code Playgroud)
GCC 6.3和Clang 4.0都没有接受我的代码.
是否与我对C++模板演绎阶段缺乏了解有关?1400页长规格实际上对我的问题有明确的答案吗?
总而言之,我的问题实际上可以简化为这段代码(没有lambda,单个参数),并且它在C++ 14下无效(感谢@BaummitAugen和@NirFriedman)
template <typename T>
void f(T x = 0) { }
int main() {
f();
}
Run Code Online (Sandbox Code Playgroud) 我看过(很多)带有和不带参数的装饰器的教程和片段,包括我认为是规范答案的那两个:带有参数的装饰器、带有 @ 语法的 python 装饰器参数,但我不明白为什么我的代码出现错误。
以下代码位于文件中decorators.py:
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Description: decorators
"""
import functools
def repeat(nbrTimes=2):
'''
Define parametrized decorator with arguments
Default nbr of repeats is 2
'''
def real_repeat(func):
"""
Repeats execution 'nbrTimes' times
"""
@functools.wraps(func)
def wrapper_repeat(*args, **kwargs):
while nbrTimes != 0:
nbrTimes -= 1
return func(*args, **kwargs)
return wrapper_repeat
return real_repeat
Run Code Online (Sandbox Code Playgroud)
我从语法检查器得到的第一个警告是nbrTimes“未使用的参数”。
我在 python3 交互式控制台中测试了上述内容:
>>> from decorators import repeat
>>> @repeat(nbrTimes=3)
>>> …Run Code Online (Sandbox Code Playgroud) 有谁知道为什么调用method1不能编译而调用method2可以编译?
class MyApp {
interface X {
fun <Q : Any, A : Any> method1(argStr: String = "", argQ: Q, argH: (A) -> Unit)
fun <Q : Any, A : Any> method2(argQ: Q, argStr: String = "", argH: (A) -> Unit)
}
fun test(x: X) {
/* Call to method1 does not work - the following errors are produced
* Error: Kotlin: Type inference failed:
* fun <Q : Any, A : Any> method1(argStr: String = …Run Code Online (Sandbox Code Playgroud) 我正在编写一个近似函数,它将两个不同的公差值作为参数:
bool Approximate(vector<PointC*>* pOutput, LineC input, double horizontalTolerance, double verticalTolerance)
Run Code Online (Sandbox Code Playgroud)
如果未设置verticalTolerance,我希望函数设置verticalTolerance = horizontalTolerance.所以,我想完成以下事情:
bool Approximate(vector<PointC*>* pOutput, LineC input, double horizontalTolerance, double verticalTolerance=horizontalTolerance)
Run Code Online (Sandbox Code Playgroud)
我知道这是不可能的,因为不允许局部变量作为默认参数.所以我的问题是,设计这个功能的最佳方法是什么?
我想到的选项是:
不要使用默认参数并使用户明确设置两个容差.
将verticalTolerance的默认值设置为负值,如果为负,则将其重置为horizontalTolerance:
bool Approximate(vector<PointC*>* pOutput, LineC input, double horizontalTolerance, double verticalTolerance=-1)
{
if (verticalTolerance < 0)
{
verticalTolerance = horizontalTolerance;
}
// Rest of function
}
Run Code Online (Sandbox Code Playgroud)在我看来,第一点不是解决方案而是旁路,第二点不是最简单的解决方案.
我知道这不是一个现实世界的问题,但我想知道:你可以使用所有默认参数访问一个没有反射/技巧的索引器吗?
例如如何调用:
public int this[string val="", int sth=5]
{
get
{
return 0;
}
set
{
}
}
Run Code Online (Sandbox Code Playgroud)
没有明确提供参数?
我会考虑类似的东西myobject[],但这显然不正确.
为什么编译器不警告我没有任何意义?
这在Python教程中有介绍,但我还是不太明白Python为什么会有这种风格。是纯粹的约定,还是有一些解释为什么 Python 对默认参数具有以下样式:
我的理解是 Python 更喜欢something=None而不是something=[]函数的默认参数。但是……为什么不使用something=[]?当然这是其他语言的约定,比如 C
以这两个例子为例,它们是等价的
def function(arr, L=[]):
L.append(arr)
return L
Run Code Online (Sandbox Code Playgroud)
和
def function(arr, L=None):
if L is None:
L = []
L.append(arr)
return L
Run Code Online (Sandbox Code Playgroud)
我的理解是,第一个是 Python 的“风格不正确”。为什么?
编辑:啊,我终于明白了。我上面不正确:这两个函数不等价。默认参数在定义函数时计算一次,而不是每次调用函数时!
请考虑以下代码
template<bool b, typename T> void foo(const T& t = []() {}) {
// implementation here
}
void bar() {
foo<true>([&](){ /* implementation here */ }); // this compiles
foo<true>(); // this doesn't compile
}
Run Code Online (Sandbox Code Playgroud)
在不编译的情况下,我得到以下错误:
error C2672: 'foo': no matching overloaded function found
error C2783: 'void foo(const T&)': could not deduce template argument for 'T'
Run Code Online (Sandbox Code Playgroud)
我认为我想要实现的目标很明确:让我们foo在没有客户提供的lambda的情况下调用它.编译器是MSVC++ 2017版本15.4.4工具集v141.
def foo(implicit i: Int = 1) = i
def bar(implicit j: Int) = foo()
bar(4)
Run Code Online (Sandbox Code Playgroud)
这段代码的计算结果为1. 因此默认值优先于隐式的j,后者被实例化为4。因此,似乎至少在这个例子中,默认参数值胜过implicit,使得 的定义foo等价于def foo(i: Int = 1) = i。
默认参数值总是胜过隐式吗?如果是,为什么这个代码是合法的(因为它令人困惑)?如果不是,反例是什么?
有没有办法获得其他行为,即与上述类似的一段代码(具有默认值 for i)将评估为4,而无需显式传递参数?
该功能hello没有任何冲突并且工作正常。
defmodule User do
defstruct [:name]
end
defmodule Greeter do
def hello(%User{} = user) do
"Hello #{user.name}"
end
def hello(name) do
"Hello #{name}"
end
end
Run Code Online (Sandbox Code Playgroud)
但是,如果我向第一个函数添加可选参数,则会出现冲突错误。
...
def hello(%User{} = user, opts \\ []) do
"Hello #{user.name}"
end
...
Run Code Online (Sandbox Code Playgroud)
错误
def hello/1 conflicts with defaults from hello/2
任何人都可以解释为什么以及如何有意义?