假设我们有该函数f,并且我需要参数b默认为空列表,但由于可变默认参数的问题而无法设置 b=[]。
其中哪一个最Pythonic,或者有更好的方法吗?
def f(a, b=None):
if not b:
b = []
pass
def f(a, b=None):
b = b or []
pass
Run Code Online (Sandbox Code Playgroud) #include <stdio.h>
void print(int a = __LINE__){printf("hello %d\n", a);}
void main(){
print();
print();
print();
print();
}
Run Code Online (Sandbox Code Playgroud)
本例中的宏__LINE__扩展为 3,因此使用相同的值调用 print 函数 4 次。有没有办法说服编译器在调用点扩展此宏,以便使用 C++11 中存在的功能6,7,8,9而不是调用 print 函数?3,3,3,3
我的用例:
在我的应用程序中,我提供了多个采用唯一 ID 的函数。每个调用站点/位置的 ID 应该是唯一的(因此,如果通过同一语句调用该函数两次,它应该收到相同的 id)。目前,用户始终必须LOCATION在调用站点手动键入宏,如下所示:
#define S1(x) #x //voodoo to concat __FILE__ and __LINE__
#define S2(x) S1(x)
#define LOCATION __FILE__ S2(__LINE__)
do_stuff1(arguments, LOCATION)
do_stuff2(arguments, LOCATION)
Run Code Online (Sandbox Code Playgroud)
如果我可以节省他们的打字时间,而不需要为每个函数创建宏,如下所示,那就更方便了:
#define do_stuff1(do_stuff1_imp(arguments, LOCATION))
#define do_stuff2(do_stuff2_imp(arguments, LOCATION))
Run Code Online (Sandbox Code Playgroud)
因此我认为默认参数可以解决问题。有什么办法可以实现这一点吗?
我正在编写此类构造函数:
element(int f=0, int a)
{
first = f;
inc = a;
current = first - inc;
}
Run Code Online (Sandbox Code Playgroud)
参数被分配给构造函数体中的成员变量。我被要求接听以下电话main()才能工作:
prog = new element(3,5);
prog = new element(5);
Run Code Online (Sandbox Code Playgroud)
我无法更改(3,5). 就像在构造函数中一样,f需要先传递,然后再传递a。但是,f如果没有传入值,则需要初始化为 0,这样第二次调用就保持f为 0,而只初始化a为 5。
这样做的问题是,如果我在构造函数签名中按此顺序放置参数,则会出现错误。
我该如何解决这个问题?
如果我有一个函数模板,它的模板参数具有默认参数,并且该函数采用类型参数的非默认参数,那么语言中允许该永远不会使用的默认参数有什么意义?:
template <class T = int>
void foo(T x){cout << x << endl;}
int main()
{
foo("hi"); // T is char const *
foo(); // error
}
Run Code Online (Sandbox Code Playgroud)
如您所见T=int,永远无法使用,因为该函数没有默认参数,因此此上下文中的编译器总是T从传递给foo.
考虑以下代码:
void foo(int* = 0); // (1)
void foo(int = 0); // (2)
int main() {
foo(0); // OK, calls (2)
foo(); // error, ambiguous overload
}
Run Code Online (Sandbox Code Playgroud)
GCC 和 clang 都是这样的,但我不相信它是正确的。
[expr.call] p6只是说:
如果没有相应的参数,则使用参数的默认参数。
这表明,一旦进行函数调用,foo将变为foo(0)且0必须将其转换为int*for (1)。
因此,我相信这两个函数调用应该是有效的。然而,有没有与这个想法相矛盾的措辞呢?默认参数的转换是否被视为“自由”,以便它们不会对转换序列产生影响?
这是我的一段代码......
def contactMaster(data="",url= str(chosenMaster)+"todolist"):
print "url: "+url
Run Code Online (Sandbox Code Playgroud)
它只打印"todolist"而不是"http://www.mysite.com/blah/1234/todolist"
为什么不工作?
让我说我有这个prog.cc文件:
struct MyStruct
{
unsigned int X : 2;
unsigned int Y : 2;
unsigned int Spare : 28;
};
void MyFunc (int x, MyStruct myStruct = 0);
int main ()
{
MyStruct myStr;
myStr.X = 1;
myStr.Y = 0;
MyFunc(6);
}
void MyFunc (int x, MyStruct myStruct)
{
x += 10;
}
Run Code Online (Sandbox Code Playgroud)
使用GCC 4.4.7编译时,出现此错误:
prog.cc:7:错误:'MyStruct myStruct'的默认参数类型为'int'
现在,我理解错误,但仍然 - 我该如何解决这个问题?我知道我需要以某种方式投射int到MyStruct,但两者都是
MyStruct myStruct = (MyStruct)0
Run Code Online (Sandbox Code Playgroud)
和
MyStruct myStruct = static_cast<MyStruct>0
Run Code Online (Sandbox Code Playgroud)
失败了:
prog.cc:7:错误:没有匹配函数来调用'MyStruct :: MyStruct(int)'
prog.cc:1:注意:候选人是:MyStruct :: MyStruct() …
上下文:我认为使用以下编译的SSCCEcompile: g++ -std=c++11 main.cpp将对固定大小的数组进行零初始化arr:
void foo(int arr[4] = {0}) { }
int main(int argc, char const *argv[]) {
foo();
return 0;
}
Run Code Online (Sandbox Code Playgroud)
然而,我调试gdb并发现arr = 0x0(空)。我(疯狂地)猜测这是因为int arr[4]很像,int* arr但另外告诉编译器只允许长度为 4 的数组。因此,实际发生的情况是,int arr* = {0}即我只是使用初始化列表来对指针进行零初始化。
我知道我可以通过恢复使用重载而不是默认参数来规避这个问题:
void foo(int arr[4]) { }
void foo() {
int arr[4] = {0};
foo(arr);
}
Run Code Online (Sandbox Code Playgroud)
正如预期的那样,这确实给了我一个零初始化的固定大小数组foo。然而,我认为通过使用一些默认参数将这两个重载函数合并为一个函数会很好,类似于 SSCCE。
问题:C++11 中默认参数固定大小数组的零初始化是否可行。如果是这样,怎么办?
特别是在自动调用基类构造函数的上下文中:具有默认值的基类的单个参数构造函数是否与默认构造函数(不带参数的构造函数)以相同的方式(例如,如果未指定,则自动调用)?
struct base {
base(int value = 42) {}
};
struct derived : public base {
derived() {} // automatic call to base::base(int) ?
};
Run Code Online (Sandbox Code Playgroud)
编辑:以下与问题无关,这只是我如何想到的。以下代码甚至不显示我所看到的崩溃。请参阅下面的实际示例。
考虑一下:
#include <sstream>
// C++98, std::ostringstream(ios_base::openmode mode = ios_base::out) available
struct OhNo : public std::ostringstream {
OhNo() {
}
void Crash() const {
this->str();
}
};
// later: OhNo f; f.Crash();
Run Code Online (Sandbox Code Playgroud)
std::ostringstream(在C ++ 11之前)没有无参构造函数。只有一个具有单个参数和默认值。 上面(是的)确实存在,如果没有可用的自变量构造函数,则会自动调用基类构造函数。OhNo没有调用它的基类的构造函数。
GCC 5.4.0可以很好地进行编译,但是以后会出现段错误(由于未初始化的基类,这是 另一个问题)。Clang 7.0.0也可以很好地编译,并且可以正常运行代码。
谁是对的?是否需要在此处手动调用基类构造函数? …
c++ default-constructor language-lawyer default-arguments c++98
我想编写一个通用函数,它接受两个输入变量var1,var2并返回两者的串联。
每个变量都有默认值None,可以是单个元素或一个list.
预期结果应该是一个列表(即使两个var1和var2的None,它应该返回一个空列表[])。
下面是我的功能:
def my_func(var1=None, var2=None):
if not isinstance(var1, list):
var1 = [var1]
if not isinstance(var2, list):
var2 = [var2]
return var1 + var2
Run Code Online (Sandbox Code Playgroud)
当我只输入一个变量时,我得到以下信息:
def my_func(var1=None, var2=None):
if not isinstance(var1, list):
var1 = [var1]
if not isinstance(var2, list):
var2 = [var2]
return var1 + var2
Run Code Online (Sandbox Code Playgroud)
我想得到
>>> lst = my_func(var2=[1, 2, 3])
>>> print(lst)
[None, 1, 2, 3]
Run Code Online (Sandbox Code Playgroud)
有什么方法可以在函数中转换None …
我试图在另一个类的构造函数的参数的默认赋值中调用一个类的构造函数,但是我遇到了构造函数未正确调用的问题。这里发生了什么?
本Bad类是不工作的情况和Good类是一个丑陋的解决办法来解决这个问题。Base.i每次Base.__init__调用构造函数时,该值都会增加,并且可以看出,它没有为o2对象正确增加,但似乎为每个o1,o3和正确增加o4。
class Base:
i = 0
def __init__(self):
Base.i += 1
self.i = Base.i
class Bad:
def __init__(self, base = Base()):
self.base = base
class Good:
def __init__(self, base = None):
if base is None:
self.base = Base()
else:
self.base = base
if __name__ == "__main__":
o1 = Bad()
o2 = Bad()
print("Bad:")
print(f"o1.i: {o1.base.i}")
print(f"o2.i: {o2.base.i}")
o3 = Good() …Run Code Online (Sandbox Code Playgroud) python constructor initialization default-constructor default-arguments
我有一堂课
class Base {
public:
virtual ~Base() {}
virtual string returnString() = 0;
};
class B : public A {
public:
string returnString() { return "string"; }
}
class C : public A {
public:
string returnString() { return ""; }
}
Run Code Online (Sandbox Code Playgroud)
和功能
string returnStringFunction(...);
Run Code Online (Sandbox Code Playgroud)
我希望能够传递 C 类型的对象,但默认情况下,我希望此函数使用动态创建的 B 类型对象。
我记得使用过这样的东西:
string returnStringFunction(const A& a = *std::make_unique<B>())
Run Code Online (Sandbox Code Playgroud)
或者
string returnStringFunction(const std::unique_ptr<A> a = std::make_unique<B>())
Run Code Online (Sandbox Code Playgroud)
函数体示例:
string returnStringFunction(...) {
return a->returnString();
}
Run Code Online (Sandbox Code Playgroud)
但是这两个解决方案即使它们通常在我的“沙盒”环境中编译和工作,它们也会在工作区上生成SIGFAULT。知道是什么原因造成的或如何更好地解决它吗?
提前致谢