What is this crazy C++11 syntax == struct : bar {} foo {};?
First, we'll take a bog-standard abstract UDT (User-Defined Type):
struct foo { virtual void f() = 0; }; // normal abstract type
foo obj;
// error: cannot declare variable 'obj' to be of abstract type 'foo'
Let's also recall that we can instantiate the UDT at the same time that we define it:
struct foo { foo() { cout << "!"; } }; // just a definition
struct foo { foo() { cout << "!"; } } instance; // so much more
// Output: "!"
Let's combine the examples, and recall that we can define a UDT that has no name:
struct { virtual void f() = 0; } instance; // unnamed abstract type
// error: cannot declare variable 'instance' to be of abstract type '<anonymous struct>'
We don't need the proof about the anonymous UDT any more, so we can lose the pure virtual function. Also renaming instance
to foo
, we're left with:
struct {} foo;
Getting close.
Now, what if this anonymous UDT were to derive from some base?
struct bar {}; // base UDT
struct : bar {} foo; // anonymous derived UDT, and instance thereof
Finally, C++11 introduces extended initialisers, such that we can do confusing things like this:
int x{0};
And this:
int x{};
And, finally, this:
struct : bar {} foo {};
This is an unnamed struct deriving from bar, instantiated as foo with a blank initializer.
Have a C++ variable able to be either Class Foo or Class Bar
Instead of auto
you'd want a pointer to the base class
int decider(int type) {
Printer* prt;
if (type == 1) {
prt = new CSV;
} else {
prt = new TXT;
}
prt->header();
}
but instead of raw pointers and new
(since you are leaking memory from a missing delete
) I'd instead use smart pointers here
#include <memory>
int decider(int type) {
std::unique_ptr<Printer> prt;
if (type == 1) {
prt = std::make_unique<CSV>();
} else {
prt = std::make_unique<TXT>();
}
prt->header();
}
As noted by @FredLarson you also need a virtual destructor in your base class
class Printer {
public:
virtual ~Printer() = default;
virtual void header() = 0;
};
you should also inherit publicly from the base class
class CSV : public Printer {
...
};
class TXT : public Printer {
...
};
Global qualification in base specifier
This is just to do with parsing. From §2.5.3
If the input stream has been parsed into preprocessing tokens up to a given character, the next preprocessing token is the longest sequence of characters that could constitute a preprocessing token, even if that would cause further lexical analysis to fail.
Basically, it has to take the longest sequence of characters, so :::
is always parsed as ::
:
in the same way that x+++y
is always parsed as x
++
+
y
.
This is referred to as Maximal Munch parsing.
Can someone tell me what this crazy c++ statement means in C#?
size_t
is a typedef for an unsigned integer type. It is used for sizes of things, and may be 32 or 64 bits in size. The particular size of a size_t
is implementation defined, but it is unsigned.
I suppose in C# you could use a 64-bit unsigned integer type.
All sizeof
does is return the size in bytes of a C++ type. Every type takes up a certain quantity of room, and sizeof
returns that size.
What your code is doing is computing the number of doubles (64-bit floats) that the DeltaTTable
takes up. Essentially, it's ensuring that the table is larger than some size based on y
, whatever that is.
There is no equivalent of sizeof
in C#, nor does it need it. There is no reason for you to port this code to C#.
C++ syntax, is this a lambda
What a lambda looks like:
// This is the basics of a lambda expression.
[ /* Optional Capture Variables */ ]( /*Optional Parameters */ ) {
/* Optional Code */
}
So the simplest lambda is:
[](){}
What are the different parts:
Capture Variables: Variables from the current visible scope
that can be used by the lambda.
Parameters: Just like a normal function, these are parameters
that are passed to the parameter when it is invoked.
Code: This is the code that is executed and uses the
above mentioned variables when the lambda is invoked.
I think it is useful to consider what is likely (not specified) going on behind the senes. A Lamda is just syntactic sugar for a functor (a callabale object).
int main()
{
int data = 12;
// define the lambda.
auto lambda = [&data](int val){
std::cout << "Lambda: " << (val + data) << "\n";
};
lambda(2); // activate the lambda.
}
This is semantically equivalent to the following:
class CompilerGeneratedClassNameLambda
{
int& data;
public:
CompilerGeneratedClassNameLambda(int& data)
: data(data)
{}
void operator()(int val) const {
std::cout << "Lambda: " << (val + data) << "\n";
}
};
int main()
{
int data = 12;
CompilerGeneratedClassNameLambda lambda(data);
lambda(2); // activate the lambda.
}
In your code. This part is the lambda:
[&p,buf](std::error_code ec, size_t n) {
std::cout << "Received " << n << " bytes (" << ec.message() << "): '";
std::cout.write(boost::asio::buffer_cast<char const*>(buf), n) << "'" << std::endl;
if (!ec) read_loop(p, buf);
}
Related Topics
How to Print the Value of Nullptr on Screen
Can't Use Structure in Global Scope
How to Do Performance Test Using the Boost Library for a Custom Library
What Are the Rules Governing C++ Single and Double Precision Mixed Calculations
Opencv Imshow Not Displaying Image in Osx
Is It Possible for the Executable to Ask for Administrator Rights? (Windows 7)
Array of Size Defined by Not Constant Variable
How Can Duff's Device Code Be Compiled
Do I Get a Finished Slot If I Start Qprocess Using Startdetached
Wait for Input for a Certain Time
Explicitly Initialize Dword to 1, But Debugger Shows Wildly Out of Range Value
Vs: Unexpected Optimization Behavior with _Bitscanreverse64 Intrinsic
Combining Two Lists by Key Using Thrust
Static Const Member Value VS. Member Enum:Which Method Is Better & Why
How to Test Whether Class B Is Derived from Template Family of Classes