Assignment - 10 Solution
Assignment - 10 Solution
Total Marks : 27
Question 1
Consider the program (in C++11) given below. [MCQ, Marks 1]
#include <iostream>
__________________ { // LINE-1
double dct = 0.05;
double getVal(double pri){
return pri * dct;
}
}
________________________ { // LINE-2
double dct = 0.07;
template<typename T>
T getVal(T pri){
return pri * dct;
}
}
int main(){
std::cout << ns1::getVal(105.0) << " ";
std::cout << ns2::getVal(105) << " " << getVal(105.0);
return 0;
}
Choose the appropriate option to fill in the blanks at LINE-1 and LINE-2 so that the output
becomes
5.25 7 7.35
1
d) LINE-1: inline namespace ns1
LINE-2: inline namespace ns2
Answer: b)
Explanation:
As per the output of ns1::getVal(105.0) and ns2::getVal(105), the ns1 and ns2 must
have basic namespace definition. However, since getVal(105.0) invoke the function getVal
from ns2, ns2 must be the default namespace. Thus, at LINE-1 and LINE-2, we must have:
namespace ns1
inline namespace ns2
2
Question 2
Consider the program (in C++11) given below. [MCQ, Marks 1]
#include <iostream>
int main( ){
int a = 1;
const int b = 1;
int& i1 = a;
const int& i2 = b;
auto x1 = i1;
auto x2 = i2; //LINE-1
std::cout << ++x1 << " " << ++x2 << " "; //LINE-2
std::cout << i1 << " " << i2;
return 0;
}
c) 2 2 2 2
d) 2 2 1 1
Answer: d)
Explanation:
Since auto never deduces adornments like cv-qualifer or reference (however, no error or excep-
tion is generated), the inferred type of x1 and x2 is int. Thus, the changes in x1 and x2 are
not reflected on i1 and i2.
3
Question 3
Consider the following code segment (in C++11). [MSQ, Marks 2]
#include <iostream>
#include <vector>
void change(std::vector<int>& iv){
auto j = 2;
for(________________ : iv) //LINE-1
i *= j;
}
int main( ){
std::vector<int> iVec { 10, 20, 30, 40 };
change(iVec);
for(auto i : iVec)
std::cout << i << ", ";
return 0;
}
Choose the appropriate option/s to fill in the blank at LINE-1 such that the output is
20, 40, 60, 80,
a) auto i
b) decltype(j) i
c) decltype((j)) i
d) decltype(iv[j]) i
Answer: c), d)
Explanation:
In options a) and b), the inferred type of i is int. Thus, the changes made in i are not
reflected in the vector iVec. So, the O/P is 20, 40, 60, 80,
In options c) and d), the inferred type of i is int&. Thus, the changes made in i are reflected
in the vector iVec.
4
Question 4
Consider the following code segment (in C++14). [MSQ, Marks 2]
#include<iostream>
struct LHS{
int i {10};
int operator()() { return i ; }
};
struct RHS{
int i {10};
int& operator()() { return i ; }
};
int main(){
LHS f1;
RHS f2;
std::cout << caller(f1) << " ";
std::cout << (caller(f2) = 100);
return 0;
}
Choose the appropriate option/s to fill in the blank at LINE-1 such that the output is 10 100.
Answer: b), d)
Explanation:
The call caller(f1) evaluates to prvalue of type int.
The call caller(f2) = 100 evaluates to lvalue of type int&.
Since plain auto never deduces to a reference, option a) fails for lvalue.
Since plain int& always deduces to a reference, option c) fails for prvalue.
Option b) and d) works for lvalue as well as prvalue. Thus these two are correct options.
5
Question 5
Consider the following code segment (in C++11). [MCQ, Marks 2]
#include <iostream>
int main( ){
int n = 10;
int& a = n;
const int& b = 10;
auto x1 = a;
auto x2 = b;
decltype(a) x3 = a;
decltype(b) x4 = a;
++x1; //LINE-1
++x2; //LINE-2
++x3; //LINE-3
++x4; //LINE-4
return 0;
}
a) LINE-1
b) LINE-2
c) LINE-3
d) LINE-4
Answer: d)
Explanation:
Since auto never deduces adornments like cv-qualifier or reference (however, no error or ex-
ception is generated), the inferred type of x1 and x2 is int. For x3, the inferred type is int&,
whereas for x4, the inferred type is const int&. Therefore, d) is the correct option.
6
Question 6
Consider the following code segment (in C++11). [MSQ, Marks 2]
#include<iostream>
#include<iomanip>
Choose the appropriate option to fill in the blank at LINE-1 such that the output is 1019CM.
a) 10.0M, 19.0CM
b) 10.0 M, 19.0 CM
c) (M)10.0, (CM)19.0
d) 10 M, 19 CM
Answer: b)
Explanation:
For user-defined numeric literal operators, the correct way to invoke them is to write them as
10.0 M, 19.0 CM.
All other options are compilation error. Even option d) is wrong as numeric literal operators
require exact type matching.
Intentionally kept as MSQ
7
Question 7
Consider the following program (in C++11). [MCQ, Marks 2]
#include <iostream>
#include <vector>
#include <initializer_list>
template<typename T>
class Number{
public:
Number() { std::cout << "1" << " "; }
Number(int n) { std::cout << "2" << " "; }
Number(std::initializer_list<int> elems) { std::cout << "3" << " "; }
Number(int n, std::initializer_list<int> elms) { std::cout << "4" << " ";
}
};
int main(){
Number<int> n1(10);
Number<int> n2({10, 20, 30});
Number<int> n3{10, 20, 30};
Number<int> n4 = {10, 20, 30};
Number<int> n5(10, {10, 20, 30});
return 0;
}
a) 2 3 3 1 4
b) 2 3 3 3 4
c) 2 3 2 1 3
d) 2 4 3 3 4
Answer: b)
Explanation:
Number<int> n1(10); invokes parameterized constructor Number(int n) { ... }.
Number<int> n2({10, 20, 30});, Number<int> n3{10, 20, 30}; and Number<int> n4 =
{10, 20, 30}; invoke the initializer list constructor Number(initializer list<int> elms){
... }.
Number<int> n5(10, {10, 20, 30}); invokes the mixed constructor
Number(int n, initializer list<int> elms){ ... }.
8
Question 8
Consider the following code segment (in C++11). [MSQ, Marks 2]
#include<iostream>
int main(){
function(50);
return 0;
}
a) LINE-1
b) LINE-2
c) LINE-3
d) LINE-4
Answer: c), d)
Explanation:
constexpr needs compile-time constant.
At LINE-1, c1 = n + 30; where n is a constexpr and 30 is a literal. Therefore, c1 is a
constexpr.
At LINE-2, c2 = n + c1 where n and c1 both are constexpr. Therefore, c2 is a constexpr.
At LINE-3, c3 = n + i; where n is a constexpr; however i is not a compile-time constant.
Therefore, c2 cannot be constexpr.
At LINE-4, c4 = n + f2(i); where n is a constexpr; however the call f2(i) fails since i is not
a compile-time constant.
9
Question 9
Consider the following code segment (in C++11). [MSQ, Marks 2]
#include <iostream>
int main(){
char s[15] = "Modern C++";
function(show, s); //LINE-1
function(show, 0); //LINE-2
function(show, s[4]); //LINE-3
function(show, nullptr); //LINE-4
return 0;
}
a) LINE-1
b) LINE-2
c) LINE-3
d) LINE-4
Answer: b), c)
Explanation:
For the call in LINE-1, the template type parameter PARA is deduced to char*. Thus, it does
not generate any compiler error.
For the call in LINE-2, the template type parameter PARA is deduced to int. Thus, it generates
a compiler error.
For the call in LINE-3, the template type parameter PARA is deduced to char. Thus, it generates
a compiler error.
For the call in LINE-4, the template type parameter PARA is deduced to std::nullptr t and
the call show(f, std::nullptr t) is syntactically correct.
10
Programming Questions
Question 1
Consider the following program (in C++11). Fill in the blanks as per the instructions given
below:
• Fill in the blanks at LINE-1 and LINE-2 with appropriate headers for the definition of
function getValue() belongs to class G and class KG.
• Fill in the blank at LINE-4 with appropriate header for function convert weight.
The program must satisfy the sample input and output. Marks: 3
#include <iostream>
class KG;
class G{
public:
G(double w) : w_(w) { }
KG getValue();
void print(){ std::cout << w_ << "G "; }
private:
double w_;
};
class KG{
public:
KG(double w) : w_(w) { }
G getValue();
void print(){ std::cout << w_ << "KG "; }
private:
double w_;
};
int main(){
double a, b;
std::cin >> a >> b;
G o1(a);
KG o2(b);
convert_weight(o1).print();
convert_weight(o2).print();
return 0;
}
11
Public 1
Input: 10 10
Output: 0.01KG 10000G
Public 2
Input: 2000 20
Output: 2KG 20000G
Private
Input: 50 500
Output: 0.05KG 500000G
Answer:
LINE-1: KG G::getValue()
LINE-2: G KG::getValue()
LINE-3: template <typename T>
Or
LINE-3: template <class T>
LINE-4: auto convert weight(T w) -> decltype(w.getValue())
Or
LINE-4: decltype(auto) convert weight(T w)
Explanation:
At LINE-1 and LINE-2 the header for getValue() function can be written as:
KG G::getValue()
and
G KG::getValue()
At LINE-3 the template, and at LINE-4 the header for function convert weight can be written
as:
template <typename T> or template <class T>
and
auto convert weight(T w) -> decltype(w.getValue()) in C++11/14
or
decltype(auto) convert weight(T w) in C++14
12
Question 2
Consider the following program in C++11/14. Fill in the blanks as per the instructions given
below:
• at LINE-1 with appropriate header and initialization list for the copy constructor,
• at LINE-2 with the appropriate header for copy assignment operator overload,
• at LINE-3 with appropriate header and initialization list for the move constructor,
• at LINE-4 with the appropriate header for move assignment operator overload,
#include <iostream>
#include <vector>
class Integer {
public:
Integer(){}
Integer(int i) : ip_(new int(i)) { }
__________________________________ { } // LINE-1: copy constructor
_______________________________ { // LINE-2: copy assignment
if (this != &n) {
delete ip_;
ip_ = new int(*(n.ip_) * 10);
}
return *this;
}
~Integer() { delete ip_; }
__________________________ { n.ip_ = nullptr; } // LINE-3: move constructor
____________________________ { // LINE-4: move assignment
if (this != &d) {
ip_ = d.ip_;
d.ip_ = nullptr;
}
return *this;
}
void show(){
if(ip_ == nullptr)
std::cout << "moved : ";
else
std::cout << *ip_ << " : ";
}
private:
int* ip_ {nullptr};
};
int main(){
int a;
std::cin >> a;
Integer n1(a);
Integer n2 = n1;
13
Integer n3;
n3 = n1;
n1.show();
n2.show();
n3.show();
Integer n4 = std::move(n1);
Integer n5;
n5 = std::move(n1);
n1.show();
n4.show();
n5.show();
return 0;
}
Public 1
Input: 5
Output: 5 : 25 : 50 : moved : 5 : moved :
Public 2
Input: -10
Output: -10 : -50 : -100 : moved : -10 : moved :
Private
Input: 1
Output: 1 : 5 : 10 : moved : 1 : moved :
Answer:
LINE-1: Integer(const Integer& n) : ip (new int(*(n.ip ) * 5))
LINE-2: Integer& operator=(const Integer& n)
LINE-3: Integer(Integer&& n) : ip (n.ip )
LINE-4: Integer& operator=(Integer&& d)
Explanation:
As per the output specified, the header and initialization list for copy constructor at LINE-1
is:
Integer(const Integer& n) : ip (new int(*(n.ip ) * 10)),
the header for copy assignment operator for copy assignment is:
Integer& operator=(const Integer& n),
the header and initialization list for move constructor at LINE-3 is:
Integer(Integer&& n) : ip (n.ip ),
the header for move assignment at LINE-4 is:
Integer& operator=(Integer&& d).
14
Question 3
Consider the following program (in C++11). Fill in the blanks as per the instructions given
below:
• Fill in the blank at LINE-2 to complete the header for function inner product.
The program must satisfy the sample input and output. Marks: 3
#include <iostream>
#include <vector>
_________________________ //LINE-1
void inner_product(________________________) { //LINE-2
_______________________________; // LINE-3: define new type Tmp
/* Don't edit the following part */
Tmp sum = 0;
int main(){
float a;
int b;
double c;
std::vector<float> Vec1;
std::vector<int> Vec2;
for(int i = 0; i < 3; i++) {
std::cin >> a;
Vec1.push_back(a);
}
for(int i = 0; i < 3; i++) {
std::cin >> b;
Vec2.push_back(b);
}
inner_product(Vec1, Vec2);
return 0;
}
Public 1
Input:
1.5 2.5 3.5
1 2 3
Output: 17
15
Public 2
Input:
5.5 3.0 4.5
11 12 13
Output: 155
Private
Input:
3.14 3.15 3.15
10 20 30
Output: 188.9
Answer:
LINE-1: template<typename U, typename V>
Or
LINE-1: template<class U, class V>
LINE-2: std::vector<U>& v1, std::vector<V>& v2
LINE-3: typedef decltype(v1[0] * v2[0]) Tmp
Explanation:
At LINE-1, the appropriate template can be defined as:
template<typename U, typename V>
or template<class U, class V>
At LINE-2 the header for function inner product can be written as:
void inner product(std::vector<U>& v1, std::vector<V>& v2)
At LINE-3 the new type Tmp can be created as:
typedef decltype(v1[0] * v2[0]) Tmp
16