在 C++ 中将默认参数值放在哪里?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/4989483/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Where to put default parameter value in C++?
提问by Thomson
What's the place for the default parameter value? Just in function definition, or declaration, or both places?
默认参数值的位置是什么?只是在函数定义或声明中,或两者兼而有之?
回答by Marcelo Cantos
Default parameter values must appear on the declaration, since that is the only thing that the caller sees.
默认参数值必须出现在声明中,因为这是调用者看到的唯一内容。
EDIT:As others point out, you canhave the argument on the definition, but I would advise writing all code as if that wasn't true.
编辑:正如其他人指出的那样,您可以对定义进行争论,但我建议编写所有代码,就好像那不是真的一样。
回答by sharptooth
You can do either, but never both. Usually you do it at function declaration and then all callers can use that default value. However you can do that at function definition insteadand then only those who see the definition will be able to use the default value.
你可以两者都做,但不能两者都做。通常您在函数声明时执行此操作,然后所有调用者都可以使用该默认值。但是,您可以在函数定义中执行此操作,然后只有看到定义的人才能使用默认值。
回答by 6502
C++ places the default parameter logic in the callingside, this means that if the default value expression cannot be computed from the calling place, then the default value cannot be used.
C++将默认参数逻辑放在调用方,这意味着如果不能从调用方计算默认值表达式,则不能使用默认值。
Other compilation units normally just include the declaration so default value expressions placed in the definition can be used only in the defining compilation unit itself (and after the definition, i.e. after the compiler sees the default value expressions).
其他编译单元通常只包含声明,因此放置在定义中的默认值表达式只能在定义编译单元本身中使用(并且在定义之后,即在编译器看到默认值表达式之后)。
The most useful place is in the declaration (.h) so that all users will see it.
最有用的地方是在声明 (.h) 中,以便所有用户都能看到它。
Some people like to add the default value expressions in the implementation too (as a comment):
有些人也喜欢在实现中添加默认值表达式(作为注释):
void foo(int x = 42,
int y = 21);
void foo(int x /* = 42 */,
int y /* = 21 */)
{
...
}
However, this means duplication and will add the possibility of having the comment out of sync with the code (what's worse than uncommented code? code with misleading comments!).
然而,这意味着重复,并且会增加注释与代码不同步的可能性(什么比未注释的代码更糟糕?带有误导性注释的代码!)。
回答by GeertVc
Although this is an "old" thread, I still would like to add the following to it:
虽然这是一个“旧”线程,但我仍然想添加以下内容:
I've experienced the next case:
我经历了下一个案例:
- In the header file of a class, I had
- 在一个类的头文件中,我有
int SetI2cSlaveAddress( UCHAR addr, bool force );
int SetI2cSlaveAddress( UCHAR addr, bool force );
- In the source file of that class, I had
- 在那个类的源文件中,我有
int CI2cHal::SetI2cSlaveAddress( UCHAR addr, bool force = false ) { ... }
int CI2cHal::SetI2cSlaveAddress( UCHAR addr, bool force = false ) { ... }
As one can see, I had put the default value of the parameter "force" in the class source file, not in the class header file.
如您所见,我将参数“force”的默认值放在类源文件中,而不是放在类头文件中。
Then I used that function in a derived class as follows (derived class inherited the base class in a public way):
然后我在派生类中使用该函数如下(派生类以公共方式继承基类):
SetI2cSlaveAddress( addr );
SetI2cSlaveAddress( addr );
assuming it would take the "force" parameter as "false" 'for granted'.
假设它将“force”参数视为“false”“理所当然”。
However, the compiler (put in c++11 mode) complained and gave me the following compiler error:
但是,编译器(置于 c++11 模式)抱怨并给了我以下编译器错误:
/home/.../mystuff/domoproject/lib/i2cdevs/max6956io.cpp: In member function 'void CMax6956Io::Init(unsigned char, unsigned char, unsigned int)':
/home/.../mystuff/domoproject/lib/i2cdevs/max6956io.cpp:26:30: error: no matching function for call to 'CMax6956Io::SetI2cSlaveAddress(unsigned char&)'
/home/.../mystuff/domoproject/lib/i2cdevs/max6956io.cpp:26:30: note: candidate is:
In file included from /home/geertvc/mystuff/domoproject/lib/i2cdevs/../../include/i2cdevs/max6956io.h:35:0,
from /home/geertvc/mystuff/domoproject/lib/i2cdevs/max6956io.cpp:1:
/home/.../mystuff/domoproject/lib/i2cdevs/../../include/i2chal/i2chal.h:65:9: note: int CI2cHal::SetI2cSlaveAddress(unsigned char, bool)
/home/.../mystuff/domoproject/lib/i2cdevs/../../include/i2chal/i2chal.h:65:9: note: candidate expects 2 arguments, 1 provided
make[2]: *** [lib/i2cdevs/CMakeFiles/i2cdevs.dir/max6956io.cpp.o] Error 1
make[1]: *** [lib/i2cdevs/CMakeFiles/i2cdevs.dir/all] Error 2
make: *** [all] Error 2
But when I added the default parameter in the headerfile of the base class:
但是当我在基类的头文件中添加默认参数时:
int SetI2cSlaveAddress( UCHAR addr, bool force = false );
int SetI2cSlaveAddress( UCHAR addr, bool force = false );
and removed it from the source file of the base class:
并将其从基类的源文件中删除:
int CI2cHal::SetI2cSlaveAddress( UCHAR addr, bool force )
int CI2cHal::SetI2cSlaveAddress( UCHAR addr, bool force )
then the compiler was happy and all code worked as expected (I could give one or two parameters to the function SetI2cSlaveAddress()
)!
然后编译器很高兴,所有代码都按预期工作(我可以给函数提供一两个参数SetI2cSlaveAddress()
)!
So, not only for the user of a class it's important to put the default value of a parameter in the header file, also compiling and functional wise it apparently seems to be a must!
因此,不仅对于类的用户来说,将参数的默认值放在头文件中很重要,而且编译和功能明智显然似乎是必须的!
回答by Tony Delroy
If the functions are exposed - non-member, public or protected - then the caller should know about them, and the default values mustbe in the header.
如果函数是公开的——非成员的、公共的或受保护的——那么调用者应该知道它们,并且默认值必须在标题中。
If the functions are private and out-of-line, then it does make sense to put the defaults in the implementation file because that allows changes that don't trigger client recompilation (a sometimes serious issue for low-level libraries shared in enterprise scale development). That said, it is definitely potentially confusing, and there is documentation value in presenting the API in a more intuitive way in the header, so pick your compromise - though consistency's the main thing when there's no compelling reason either way.
如果函数是私有的和外联的,那么将默认值放在实现文件中是有意义的,因为这允许不会触发客户端重新编译的更改(对于企业级共享的低级库有时是一个严重问题发展)。也就是说,这肯定会令人困惑,并且在标题中以更直观的方式呈现 API 具有文档价值,因此请选择您的折衷方案 - 尽管在没有令人信服的理由的情况下,一致性是最重要的。
回答by relaxxx
One more point I haven't found anyone mentioned:
还有一点我没有发现有人提到:
If you have virtual method, each declaration can have its own default value!
如果你有虚方法,每个声明都可以有自己的默认值!
It depends on the interface you are calling which value will be used.
这取决于您调用的接口将使用哪个值。
Example on ideone
struct iface
{
virtual void test(int a = 0) { std::cout << a; }
};
struct impl : public iface
{
virtual void test(int a = 5) override { std::cout << a; }
};
int main()
{
impl d;
d.test();
iface* a = &d;
a->test();
}
It prints 50
它打印 50
I strongly discourage you to use it like this
我强烈不鼓励你像这样使用它
回答by ice911
Good question... I find that coders typically use the declaration to declare defaults. I've been held to one way (or warned) or the other too based on the compiler
好问题...我发现编码人员通常使用声明来声明默认值。基于编译器,我一直坚持一种方式(或警告)或另一种方式
void testFunct(int nVal1, int nVal2=500);
void testFunct(int nVal1, int nVal2)
{
using namespace std;
cout << nVal1 << << nVal2 << endl;
}
回答by justin
the declaration is generally the most 'useful', but that depends on how you want to use the class.
声明通常是最“有用”的,但这取决于您想如何使用该类。
both is not valid.
两者都无效。
回答by Pervez Alam
You may do in either (according to standard), but remember, if your code is seeing the declaration without default argument(s) before the definition that contains default argument, then compilation error can come.
您可以(根据标准)执行任何操作,但请记住,如果您的代码在包含默认参数的定义之前看到没有默认参数的声明,则可能会出现编译错误。
For example, if you include header containing function declaration without default argument list, thus compiler will look for that prototype as it is unaware of your default argument values and hence prototype won't match.
例如,如果包含没有默认参数列表的包含函数声明的标头,则编译器将查找该原型,因为它不知道您的默认参数值,因此原型将不匹配。
If you are putting function with default argument in definition, then include that file but I won't suggest that.
如果您在定义中放置带有默认参数的函数,则包含该文件,但我不会建议这样做。
回答by SridharKritha
Adding one more point. Function declarations with default argument should be ordered from right to leftand from top to bottom.
再补充一点。带有默认参数的函数声明应该从右到左和从上到下排序。
For examplein the below function declaration if you change the declaration order then the compiler gives you a missing default parameter error. Reason the compiler allows you to separate the function declaration with default argument within the same scope but it should be in order from RIGHT to LEFT (default arguments) and from TOP to BOTTOM(order of function declaration default argument).
例如在下面的函数声明中,如果您更改声明顺序,那么编译器会给您一个缺少默认参数的错误。原因编译器允许您在同一范围内将函数声明与默认参数分开,但它应该是从右到左(默认参数)和从上到下(函数声明默认参数的顺序)的顺序。
//declaration
void function(char const *msg, bool three, bool two, bool one = false);
void function(char const *msg, bool three = true, bool two, bool one); // Error
void function(char const *msg, bool three, bool two = true, bool one); // OK
//void function(char const *msg, bool three = true, bool two, bool one); // OK
int main() {
function("Using only one Default Argument", false, true);
function("Using Two Default Arguments", false);
function("Using Three Default Arguments");
return 0;
}
//definition
void function(char const *msg, bool three, bool two, bool one ) {
std::cout<<msg<<" "<<three<<" "<<two<<" "<<one<<std::endl;
}