argument of a parameterized constructor - c++11

can someone explain me how's the argument passed in the 1st parameterized constructor working?
public:
//Constructors
Bigint();
Bigint(long long); // 1st parameterized constructor
Bigint(std::string); // 2nd parameterized constructor.

long long is a type, just like int or long. But the difference is that it's at least 64 bits wide.
See http://en.cppreference.com/w/cpp/language/types.

Related

What exactly is the in-class-initializer?

I've read many text mentioned the in-class-initializer and I've searched many question on stackoverflow, However I didn't found any precise explanation on what is the in-class-initializer. And as far as I understood the variable of build-in type declared outside any function will be default initialized by the compiler, does the in-class-initilizer doing the same action for a declared variable?
Here is a simple example for in-class initialization. It's useful for less typing, especially when more than one constructor signatures are available. It's recommend in the core guidelines, too.
class Foo {
public:
Foo() = default; // No need to initialize data members in the initializer list.
Foo(bool) { /* Do stuff here. */ } // Again, data member already have values.
private:
int bar = 42;
// ^^^^ in-class initialization
int baz{};
// ^^ same, but requests zero initialization
};
As the data members are explicitly initialized, the second part of your questions doesn't really apply to to in-class initialization.

C++ command pattern with large number of params

I am implementing a command pattern implementations with large number of actions and parameters involved. To simplify I am planning to use class that can hold all possible params to module in a map.
class ParamBag {
public:
add(int paramId, shared_ptr<IParam> param);
bool contains(int paramId);
std::shared_ptr<IParam> get(paramId);
private:
int mask;
std::map<int, std::shared_ptr<IParam>> params;
};
One clear downside of this implementation is each param has to extend from IParam interface, can I somehow simplify this.
If the one that uses the param after the get knows the type of the param, then you can use c++17 std::any, or if you must use c++11 you can try boost::any, or if none of those you can resort back to a void*.
The difference is that void* will not fail on a cast to a wrong type, where any_cast would throw an exception, or return nullptr if used with a pointer. You would also need to use a custom deleter in the std::shared_ptr in order to be able to free the void*.

Is it possible to deduce the signature of the resolved method/function overload even in case of implicit parameters conversions?

Say we have
struct Test {
void foo(int *);
void foo(float);
} test;
Given the the following method call:
test.foo(1);
The compiler will resolve it by invoking Test::foo(float), doing the implicit conversion from int to float.
Is it possible to somehow get the signature of the thus resolved method overload as a pointer type, i.e. void (Test::*)(float)?
The closest thing to a positive answer I could get is the answer to another question, however that approach will fail in case of an implicit conversion of one or more parameters.

C++ routine returning function

I have the following code which work fine. I am trying to understand the syntax. The return statement has std::plus<double>(). The double over here has the return value data type. But the function definition has the return type as std::function<double(double, double)> which indicates two double parameters. How do these two relate to each other?
#include <functional>
#include <iostream>
using namespace std;
std::function<double(double, double)> GetFunction()
{
return std::plus<double>();
}
int main()
{
auto operation = GetFunction();
int a = operation(1, 4);
std::cout << std::plus<>{}(1, 4) << '\n';
return 0;
}
There is an implicit conversion from std::plus<double> to std::function<double(double,double)>, because the former has a member call operator double operator()(double, double). See the documentation for std::function constructors.
In std::function<double(double, double)>:
The first double is the return type of the function. You can remember that by realizing that it's on the left, just like in a normal function definition.
The doubles in parentheses are the parameter types of the function, just like in a normal function definition; minus the parameter names. There are 2 since the plus function takes 2 doubles.
This makes sense if you think about it. The plus function/operator is a binary operator, meaning it takes 2 parameters of a type, and returns a single value of the same type. This is why you only need to specify a single type when you write std::plus<double>; the parameters and the return type must be the same type. It would be error prone and useless to force the caller to specify the same type 3 times.
If your question is, why there is only one double in the template parameter of std::plus but three in std::function, then the answer is this:
For std::plus, both parameters and the returntype always have to be the same, so you only have to specify it once.
std::function on the other hand can hold any function like object with any combination of parameters and returntypes, so you have to basically state each of those types individually.

Uniform initialization behavior different for different types in vector

I came across this article in which I read this example by one of the posters. I have quoted that here for convenience.
struct Foo
{
Foo(int i) {} // #1
Foo() {}
};
int main()
{
std::vector<Foo> f {10};
std::cout << f.size() << std::endl;
}
The above code, as written, emits “1” (10 is a converted to Foo by a
constructor that takes an int, then the vector’s initializer_list
constructor is called). If I comment out the line commented as #1, the
result is “10” (the initializer_list cannot be converted so the int
constructor is used).
My question is why does it emit a 10 if the int constructor is removed.
I understand that uniform initialization list works in the following order
1-Calls the initializer list if available or possible
2-Calls the default constructor if available
3-Does aggregate initialization
In the above case why is it creating 10 items in the vector since 1,2 and 3 are not possible ? Does this mean with uniform initialization a vector of items might always have different behaviors ?
Borrowing a quote from Scott Meyers in Effective Modern C++ (emphasis in original):
If, however, one or more constructors declare a parameter of type std::initializer_list, calls using the braced initialization syntax strongly prefer the overloads taking std;:initializer_lists. Strongly. If there's any way for compilers to construe a call using a braced initializer to be a constructor taking a std::initializer_list, compilers will employ that interpretation.
So when you have std::vector<Foo> f {10};, it will try to use the constructor of vector<Foo> that takes an initializer_list<Foo>. If Foo is constructible from an int, that is the constructor we're using - so we end up with one Foo constructed from 10.
Or, from the standardese, in [over.match.list]:
When objects of non-aggregate class type T are list-initialized (8.5.4), overload resolution selects the constructor
in two phases:
(1.1) — Initially, the candidate functions are the initializer-list constructors (8.5.4) of the class T and the
argument list consists of the initializer list as a single argument.
(1.2) — If no viable initializer-list constructor is found, overload resolution is performed again, where the
candidate functions are all the constructors of the class T and the argument list consists of the elements
of the initializer list.
If there is a viable initializer-list constructor, it is used. If you didn't have the Foo(int ) constructor, there would not be a viable initializer-list constructor, and overload resolution the second time around would find the constructor of vector that takes a size - and so you'd get a vector of 10 default-constructed Foos instead.

Resources