Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 6 years ago.
Improve this question
The C++ standard does not allow "= initializer-clause" form of brace-or-equal-initializer (see [dcl.init]) in mem-initializer (see [class.base.init]). For example:
struct Foo {
int x;
Foo(int y): x = y {
}
};
gives a compile-time error.
Why is that? Would there be some syntactic ambiguity if such a construct was allowed? If not, were or are there proposals to add this feature to the language?
Update. The semantics I would expect of such an initializer in this context is the same as of it in context of usual variable initialization. In my opinion, that would make initialization syntax of the language more consistent.
Update 2. As pointed out by NathanOliver, if the initialization of a member does not depend on the selected constructor and/or constructor parameters, this member can be initialized through a default member initializer (see [class.mem]). But if it does, it leaves us with using direct or list initialization.
Like others have said, it's simple not an allowed syntax in ctor initialization.
Note that, for non-primitive classes, the ctor() : xyz(...) form of initialization is actually a ctor call on the type of the member xyz. While the ctor(): xyz{...} is for aggregate initialization of either an array/list or for member initialization of structs/unions that have no ctors.
A ctor() : xyz = something would seem to have to do two things: 1) a default ctor call and 2) then call the operator= for the type of member xyz all of which would be double initialization. That is probably why it is disallowed. Of course, for non-primitive cases, I guess it could be reduced to a copy-ctor call to eliminate the double initialization.
Now, you could maybe convince some that allowing it for primitive types only would be ok, but that would likely introduce other complications into the language and compilers.
Related
I have just learned about classes in C++. I know that data members can be initialized by using the member initialization list syntax (MIL), but I think it is not very intuitive to use, and I think it is a very ugly way to assign data members.
Apparently class inheritance in C++ MUST be done through this MIL syntax. I do not understand the rationale behind this and googling did not give me answers. I am also unable to find any counter-example to this rule. Every example I saw online about inheritance requires the MIL.
So my question is: Is it possible to set up an inheritance without the MIL?
If the answer is yes, please explain how.
If the answer is no, please explain why not. (give the rationale behind mandating the MIL for inheritance)
No, that is not possible in general. If the base class has a default constructor, you can omit its initializer in the constructor of the derived class if that is appropriate. Typically though, you will want to invoke a specific constructor, and the member initializer list is the place to do that.
The reason for this is the design of the language: all "direct subobjects" of a class, meaning the base class objects and non-static data members it introduces, are actually initialized even before the body of its constructor is entered. Explicit member initializers must be given for subobjects that cannot be default-initialized, otherwise the program is ill-formed (must be rejected by compilers). For further reference, see for example cppreference on constructors and member initializer lists.
In practice this means that, while a constructor can perform additional work after initialization, constructors with empty bodies are fairly common in C++, but ones with empty member initializer lists are not.
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 1 year ago.
Improve this question
If I have 2 functions like follows:
template <typename T>
void A(int n)
{
T a[n]; // need to use this array of variables in function B without any passing
// assignment of values to a[n] variables and rest of code for function A
}
void B()
{
// need to use a[n] array here without passing
}
Can the static array T a[n] be used in function B somehow without passing the arguments to B explicitly?
Is it called function forwarding or perfect forwarding in C++?
I'm aware that creating attempting to create a static array out of a variable int isn't standard C++ and some compilers support it. My main question is can the arguments be used in B without passing?
No. Functions have a scope, names of automatic variables are inaccessible outside of that scope, and other functions are outside of that scope.
Is it called function forwarding or perfect forwarding in C++?
No, what you're asking about is not related to forwarding. Forwarding is passing of arguments which is the opposite of what you are asking for.
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 1 year ago.
Improve this question
according to https://google.github.io/styleguide/cppguide.html#Variable_Names, Data members of classes, both static and non-static, are named like ordinary nonmember variables, but with a trailing underscore.
according to https://google.github.io/styleguide/cppguide.html#Constant_Names, "Variables declared constexpr or const, and whose value is fixed for the duration of the program, are named with a leading "k" followed by mixed case." -- note the "for the duration of the program" part.
according to https://google.github.io/styleguide/cppguide.html#Access_Control "Make classes' data members private, unless they are constants. This simplifies reasoning about invariants, at the cost of some easy boilerplate in the form of accessors (usually const) if necessary."
So... I think this leaves a bit of room for interpretation, and I wanted to know if anybody knows what the spirit of the standard is...
class A {
const int size_;
public:
A(int size) : size_(size) {}
};
Is the trailing underscore a sign of "private"-ness or "class"-ness?
Is the const field supposed to be "kSize" or "size_"?
If it is moved to be public, should it be "size"?
In your example:
class A {
const int size_;
This member variable is not a "constant" for the purposes of the style guide. Its value cannot be changed after construction, but is different per instance. A "constant" inside a class would be constexpr or static const or enum. As it stands, it is not a constant so does not get a k prefix.
To answer your specific questions individually:
The trailing underscore tells you it's a class member variable.
size_ because it's not a "constant" in terms of the style guide.
Making it public would violate the style guide, so this doesn't really have an answer.
Finally, note that const member variables inhibit the compiler-generated assignment operator, which is one reason you don't see them that often.
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 8 years ago.
Improve this question
So we were doing some peer review, and this minor disagreement rose up,
Should the default constructor be defined even if it does nothing, or should we let the compiler define it?
So far, none of the sides could come up with any major advantages or disadvantages. What are the pros and cons of each style and which one is considered "cleaner"?
This is likely to be closed as "primarily opinion-based," but I can give you some objective points to consider:
If you don't define the default constructor, and someone later adds a constructor with parameters and forgets to also add the parameterless constructor, the default constructor will go away and that could break existing code. Explicitly defining it ensures that even if someone adds an overloaded constructor later, the parameterless one is still there.
If the constructor is declared in the header and defined out-of-line (in a .cc/.cpp file), then the implementation can later be modified with dependent code only needing to be re-linked. Declaring a constructor after the fact necessarily affects the header, requiring recompilation of dependent code.
An empty out-of-line constructor will still need to be called, incurring a small run-time cost, whereas with an implicitly provided default constructor the compiler can see that nothing needs to be done and avoid the call.
Defining it explicitly requires more typing and results in more lines of code. There is a small but nonzero cost associated with this (time taken to type it in, and time taken for readers of the code to read through it).
Defining it explicitly disqualifies the class from being an aggregate class, unless you use =default in C++11.
Yes, these points are contradictory. I think you will find that the prevailing opinion is not to define it explicitly, but as far as the language is concerned there is no correct or incorrect way. (Unless you need your type to be an aggregate.)
Without any user c'tors
You should only implement your own default constructor it it does anything else then the one the compiler would generate.
If you want to give the reader a hint, you can replace the implementation with = default in C++11.
struct MyObject {
// only members that the compiler initializes fine
std::vector<int> data_;
MyObject() = default;
};
or, if you don't wan to be that verbose (or before C++11):
struct MyObject {
// only members that the compiler initializes fine
std::vector<int> data_;
};
With other user c'tors
The compiler will not generate a default c'tor if you provide any other c'tor. in this case you should only provide a default c'tor if it makes sense, semantically -- not because it's "nice" to have one :-)
Pros and Cons
Explicitly providing an unnecessary default c'tor
(-) it is bad to have more code then necessary
(o) except when the gained clarity outweighs the longer source code (= default)
(-) a compiler-generated default c'tor will be close to optimal
(-) if you start providing an unnecessary member ("unnecessary", because it would be generated), you later end up defining all of the auto generated ones, i.e. default-c'tor, destructor, copy, move, assign and move-assign. You really don't want to end up there.
(-) will you know if you should mark the default c'tor with noexcept? The compiler often does. Don't waist your brain powers where the compiler can help you.
I really can not see any clear (+), but that's just me.
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 9 years ago.
Improve this question
I used clang3.3 with netbeans on linux. All in C++11. And I have a question about initialization
int main()
{
int i();
}
The following code is compiled but not work properly. This value will not defined by debugger and cannot be printable. I wanted describe int with default value. Instead I can write "int{}" and it will be a perfect default initialization. But I want understand what I wrote here, just want.
Second question. Its about lambda. I want to know how lamda can be described without auto keyword.
auto lambda = [&]()mutable->int{};
Simple, what I can write here instead auto and compiler will not give me an error ? I just want understand.
Ad 1.
You've been bitten by the most vexing parse. Basically, C++ grammar causes ambiguities between statements and declarations in certain cases. In such cases, the input is interpreted as a declaration. Since int i() can be interpreted as an integer variable definition, or a function declaration, it is interpreted as a declaration of parameterless function i, returning int.
Ad 2.
As for the second question, C++11 Standard §5.1.2/3 says it all:
The type of the lambda-expression (...) is a unique, unnamed non-union class type — called the closure type (...)
So, there is no way to refer to it other than using auto.
Thats not a variable default initialization, its a function declaration, thanks to most-vexing-parse.
In a few words, the standard says if an expression can be evaluated as a function declaration, or as something else, it will be evaluated as a function declaration.
In your case, a function a without parameters and int as return value.