Online Book Reader

Home Category

Professional C__ - Marc Gregoire [356]

By Root 1259 0
for initialization. Both classes also have an operator+ as member method. Here is the header file:

#include

// Forward class declarations

class MyInt;

class MyString;

class MyInt

{

public:

MyInt(int i) : m_i(i) {}

MyInt operator+(const MyString& rhs) const;

int getInt() const { return m_i; }

protected:

int m_i;

};

class MyString

{

public:

MyString(std::string str) : m_str(str) {}

MyString operator+(const MyInt& rhs) const;

const std::string& getString() const { return m_str; }

protected:

std::string m_str;

};

Code snippet from TypeInference\TypeInference.h

The implementation is as follows. This code uses two other new features of C++11: stoi() and to_string(), both of them are discussed in the “Numeric Conversions” section in Chapter 14:

MyInt MyInt::operator+(const MyString& rhs) const

{

return m_i + stoi(rhs.getString());

}

MyString MyString::operator+(const MyInt& rhs) const

{

string str = m_str;

str.append(to_string(rhs.getInt()));

return str;

}

Code snippet from TypeInference\TypeInference.cpp

With this implementation you will get a different result depending on the order of the arguments to the addition operator. For example:

MyInt i(4);

MyString str("5");

MyInt a = i + str;

MyString b = str + i;

Code snippet from TypeInference\TypeInference.cpp

In this case, the type of variable a should be MyInt and the type of variable b should be MyString.

Imagine that you want to write a function template to perform the addition. You can write the following:

template

Result DoAddition(const T1& t1, const T2& t2)

{

return t1 + t2;

}

Code snippet from TypeInference\TypeInference.cpp

As you can see, it requires you to specify three template parameters: the type of the first operand, the type of the second operand, and the type of the result of performing the addition. You can call this function template as follows:

auto c = DoAddition(i, str);

Code snippet from TypeInference\TypeInference.cpp

This is obviously not that elegant because you need to manually specify the type of the return value. After reading about the decltype keyword, you might want to try to fix this issue as follows:

template

decltype(t1 + t2) DoAddition(const T1& t1, const T2& t2)

{

return t1 + t2;

}

However, this will not work because at the time of parsing the decltype keyword, the compiler doesn’t know t1 and t2 yet. They become known later in the function prototype. The correct solution is to combine the alternative function syntax with the decltype keyword as shown in the following implementation:

template

auto DoAddition2(const T1& t1, const T2& t2) -> decltype(t1 + t2)

{

return t1 + t2;

}

Code snippet from TypeInference\TypeInference.cpp

With this implementation you can call DoAddition2() as follows:

auto d = DoAddition2(i, str);

auto e = DoAddition2(str, i);

Code snippet from TypeInference\TypeInference.cpp

You can see that you need not specify any function template parameters anymore because the compiler will deduce the two template parameter types based on the arguments given to DoAddition2(), and will automatically calculate the type of the return value. In this example, d will be of type MyInt and e will be of type MyString.

VARIADIC TEMPLATES


Normal templates can take only a fixed number of template parameters. For example, the following code defines a template that requires three template parameters:

template

class MyTemplate { }

C++11 introduces the notion of variadic templates. These are templates that can take a variable number of template parameters. For example, the following code defines a template that can accept any number of template parameters, using a parameter pack called Types:

template

class MyVariadicTemplate { }

The three dots behind typename are not an error. This is the syntax for variadic templates. You are allowed to put spaces before and after

Return Main Page Previous Page Next Page

®Online Book Reader