我认为以下代码非常方便且无害:
auto fn = [](bool b = false) -> int // NOT legal in C++11
{
return b ? 1 : 0;
};
Run Code Online (Sandbox Code Playgroud)
为什么C++ 11明确禁止lambda表达式的默认参数?
我只是想知道背后的理由和考虑因素.
我想知道"为什么"而不是C++ 11标准所说的"什么".
是否可以通过const引用返回默认参数的值,如以下示例所示:
https://coliru.stacked-crooked.com/a/ff76e060a007723b
#include <string>
const std::string& foo(const std::string& s = std::string(""))
{
return s;
}
int main()
{
const std::string& s1 = foo();
std::string s2 = foo();
const std::string& s3 = foo("s");
std::string s4 = foo("s");
}
Run Code Online (Sandbox Code Playgroud) c++ object-lifetime language-lawyer default-arguments reference-binding
考虑:
blank_fn = lambda *args, **kwargs: None
def callback(x, y, z=''):
print x, y, z
def perform_task(callback=blank_fn):
print 'doing stuff'
callback('x', 'y', z='z' )
Run Code Online (Sandbox Code Playgroud)
这样做的动机是我不需要输入逻辑来检查是否已经分配了回调,因为它默认为blank_fn,它什么都不做.
这有效,但是有一些原因我不应该这样做吗?它是pythonic吗?有没有更好的方法呢?是否内置了:
lambda *args, **kwargs: None
Run Code Online (Sandbox Code Playgroud) 如何绑定到接受默认参数的函数,而不指定默认参数,然后在没有任何参数的情况下调用它?
void foo(int a, int b = 23) {
std::cout << a << " " << b << std::endl;
}
int main() {
auto f = std::bind(foo, 23, 34); // works
f();
auto g = std::bind(foo, 23); // doesn't work
g();
using std::placeholders::_1;
auto h = std::bind(foo, 23, _1); // doesn't work either
h();
}
Run Code Online (Sandbox Code Playgroud) 我有Mult, Add, Div, Sub, Mod那些需要两个整数并返回其参数结果的函数。还有一个函数Calc,该函数将一个字符作为,Operator并返回一个指针,该函数返回一个整数,并接受两个整数参数,例如Mult。
Mult的第二个参数default这样的函数是So,当我调用时Calc,根据的参数值Calc返回Mult或Add... 的地址,Calc因此我只能传递一个参数。但这不适用于函数指针:
int Add(int x, int y = 2) { // y is default
return x + y;
}
int Mult(int x, int y = 2) { // y is default
return x * y;
}
int Div(int x, int y = 2) { // y is default
return y ? x …Run Code Online (Sandbox Code Playgroud) 也许我错过了一些明显的东西,但是下面的编译和运行,我不知道为什么.我知道这一点,但在下面的示例中,参数包的位置和默认参数是相反的.它是否违反了默认参数必须最后出现的规则?参数包不能具有默认值.
#include <iostream>
#include <string>
#include <tuple>
template<typename ... Ts>
struct Test
{
int i;
std::string str;
Test(int _i = 0, Ts&& ... _ts)
:
i(_i),
str(std::get<0>(std::forward_as_tuple(std::forward<Ts>(_ts)...)))
{}
};
int main()
{
Test<std::string> t(1, "huh??");
std::cout << "t.i = " << t.i << ", t.str = " << t.str << "\n";
return 0;
}
Run Code Online (Sandbox Code Playgroud)
这产生了
t.i = 1, t.str = huh??
Run Code Online (Sandbox Code Playgroud) 我很惊讶以下代码导致could not deduce template argument for T错误:
struct foo
{
template <typename T>
void bar(int a, T b = 0.0f)
{
}
};
int main()
{
foo a;
a.bar(5);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
调用a.bar<float>(5)解决了这个问题.为什么编译器不能从默认参数中推断出类型?
public struct Test
{
public double Val;
public Test(double val = double.NaN) { Val = val; }
public bool IsValid { get { return !double.IsNaN(Val); } }
}
Test myTest = new Test();
bool valid = myTest.IsValid;
Run Code Online (Sandbox Code Playgroud)
上面给出了valid==true因为没有调用默认arg的构造函数,并且使用标准默认值val = 0.0创建了对象.
如果结构是一个类,那么行为就是valid==false我所期望的.
我发现这种行为上的差异,特别是结构案例中的行为令人惊讶和不直观 - 发生了什么?stuct构造的默认arg服务是什么? 如果它无用为什么要让这个编译?
更新:澄清这里的重点不在于行为是什么 - 而是为什么在没有警告的情况下进行编译并且行为不直观.即如果没有应用默认的arg,因为在新的Test()情况下没有调用构造函数,那么为什么要让它编译?
函数(实际上是另一个类的构造函数)需要一个class tempas参数的对象.所以我定义interface itemp并包含itemp $obj为函数参数.这很好,我必须将class temp对象传递给我的函数.但是现在我想为这个itemp $obj参数设置默认值.怎么做到这一点?还是不可能?
我将把测试代码弄清楚:
interface itemp { public function get(); }
class temp implements itemp
{
private $_var;
public function __construct($var = NULL) { $this->_var = $var; }
public function get() { return $this->_var ; }
}
$defaultTempObj = new temp('Default');
function func1(itemp $obj)
{
print "Got : " . $obj->get() . " as argument.\n";
}
function func2(itemp $obj = $defaultTempObj) //error : unexpected T_VARIABLE
{
print …Run Code Online (Sandbox Code Playgroud) 这是我的代码:
struct S
{
int f() { return 1; }
int g(int arg = f()) { return arg; }
};
int main()
{
S s;
return s.g();
}
Run Code Online (Sandbox Code Playgroud)
这无法编译错误:
error: cannot call member function 'int S::f()' without object
Run Code Online (Sandbox Code Playgroud)
尝试this->f()也不起作用,因为this可能不会在该上下文中使用.
有没有办法使这个工作仍然使用默认参数?
当然可以通过不使用默认参数来解决它:
int g(int arg) { return arg; }
int g() { return g(f()); }
Run Code Online (Sandbox Code Playgroud)
然而,考虑到在"真实代码"之前有更多参数arg,以及遵循这种模式的几个函数,这会变得冗长.(如果在一个函数中有多个默认参数,那就更难看了).
NB.这个问题起初看起来很相似,但实际上他问的是如何形成一个闭包,这是一个不同的问题(并且链接的解决方案不适用于我的情况).