Читаем Thinking In C++. Volume 2: Practical Programming полностью

You can always use such explicit function template specification as in the example above, but it is often convenient to leave off the template arguments and let the compiler deduce them from the function arguments, like this:.

int z = min(i, j);

If both i and j are ints, the compiler knows that you need min, which it then instantiates automatically. The types must be identical, because the template was originally specified with only one template type argument used for both function parameters. No standard conversions are applied for function arguments whose type is specified by a template parameter. For example, if you wanted to find the minimum of an int and a double, the following attempt at a call to min would fail:.

int z = min(x, j); // x is a double

Since x and j are distinct types, no single parameter matches the template parameter T in the definition of min; so the call does not match the template declaration. You can work around this difficulty by casting one argument to the other’s type or by reverting to the fully-specified call syntax, as in:.

int z = min(x, j);

This tells the compiler to generate the double version of min, after which j can be promoted to a double by normal standard conversion rules (because the function min(const double&, const double&) would then exist).

You might be tempted to require two parameters for min, allowing the types of the arguments to be independent, like this:

template

const T& min(const T& a, const U& b) {

  return (a < b) ? a : b;

}

This is often a good strategy, but in this case it is problematic because min must return a value, and there is no satisfactory way to determine which type it should be (T or U?).

If the return type of a function template is an independent template parameter, you must always specify its type explicitly when you call it, since there is no argument from which to deduce it. Such is the case with the fromString template below.

//: C05:StringConv.h

#ifndef STRINGCONV_H

#define STRINGCONV_H

// Function templates to convert to and from strings

#include

#include

template

T fromString(const std::string& s) {

  std::istringstream is(s);

  T t;

  is >> t;

  return t;

}

template

std::string toString(const T& t) {

  std::ostringstream s;

  s << t;

  return s.str();

}

#endif // STRINGCONV_H ///:~

These function templates provide conversions to and from std:: string for any types that provide a stream inserter or extractor, respectively. Here’s a test program that includes the use of the standard library complex number type:.

//: C05:StringConvTest.cpp

#include "StringConv.h"

#include

#include

using namespace std;

int main() {

  int i = 1234;

  cout << "i == \"" << toString(i) << "\"\n";

  float x = 567.89;

  cout << "x == \"" << toString(x) << "\"\n";

  complex c(1.0, 2.0);

  cout << "c == \"" << toString(c) << "\"\n";

  cout << endl;

  i = fromString(string("1234"));

  cout << "i == " << i << endl;

  x = fromString(string("567.89"));

  cout << "x == " << x << endl;

  c = fromString< complex >(string("(1.0,2.0)"));

  cout << "c == " << c << endl;

} ///:~

The output is what you’d expect:.

i == "1234"

x == "567.89"

c == "(1,2)"

i == 1234

x == 567.89

c == (1,2)

Notice that in each of the instantiations of fromString, the template parameter is specified in the call. If you have a function template with template parameters for the parameter types as well as the return types, it is important to declare the return type parameter first; otherwise you won’t be able to omit the type parameters for the function parameters. As an illustration, consider the following well-known function template:[51] 

//: C05:ImplicitCast.cpp

template

R implicit_cast(const P& p) {

  return p;

}

int main() {

  int i = 1;

  float x = implicit_cast(i);

  int j = implicit_cast(x);

  // char* p = implicit_cast(i);

} ///:~

If you interchange R and P in the template parameter list near the top of the file, it will be impossible to compile this program because the return type will remain unspecified (since the first template parameter would be the function’s parameter type). The last line (which is commented out) is illegal because there is no standard conversion from int to char*; implicit_cast is for revealing in your code conversions that are allowed naturally.

With a little care you can even deduce array dimensions. The following example has an array-initialization function template (init2) that does just that.

//: C05:ArraySize.cpp

#include

using std::size_t;

template

void init1(T a[R][C]) {

  for (size_t i = 0; i < R; ++i)

    for (size_t j = 0; j < C; ++j)

      a[i][j] = T();

}

template

void init2(T (&a)[R][C]) {  // reference parameter

  for (size_t i = 0; i < R; ++i)

    for (size_t j = 0; j < C; ++j)

      a[i][j] = T();

}

int main() {

  int a[10][20];

  init1<10,20>(a);  // must specify

  init2(a);         // sizes deduced

} ///:~

Перейти на страницу:

Похожие книги

1С: Бухгалтерия 8 с нуля
1С: Бухгалтерия 8 с нуля

Книга содержит полное описание приемов и методов работы с программой 1С:Бухгалтерия 8. Рассматривается автоматизация всех основных участков бухгалтерии: учет наличных и безналичных денежных средств, основных средств и НМА, прихода и расхода товарно-материальных ценностей, зарплаты, производства. Описано, как вводить исходные данные, заполнять справочники и каталоги, работать с первичными документами, проводить их по учету, формировать разнообразные отчеты, выводить данные на печать, настраивать программу и использовать ее сервисные функции. Каждый урок содержит подробное описание рассматриваемой темы с детальным разбором и иллюстрированием всех этапов.Для широкого круга пользователей.

Алексей Анатольевич Гладкий

Программирование, программы, базы данных / Программное обеспечение / Бухучет и аудит / Финансы и бизнес / Книги по IT / Словари и Энциклопедии
1С: Управление торговлей 8.2
1С: Управление торговлей 8.2

Современные торговые предприятия предлагают своим клиентам широчайший ассортимент товаров, который исчисляется тысячами и десятками тысяч наименований. Причем многие позиции могут реализовываться на разных условиях: предоплата, отсрочка платежи, скидка, наценка, объем партии, и т.д. Клиенты зачастую делятся на категории – VIP-клиент, обычный клиент, постоянный клиент, мелкооптовый клиент, и т.д. Товарные позиции могут комплектоваться и разукомплектовываться, многие товары подлежат обязательной сертификации и гигиеническим исследованиям, некондиционные позиции необходимо списывать, на складах периодически должна проводиться инвентаризация, каждая компания должна иметь свою маркетинговую политику и т.д., вообщем – современное торговое предприятие представляет живой организм, находящийся в постоянном движении.Очевидно, что вся эта кипучая деятельность требует автоматизации. Для решения этой задачи существуют специальные программные средства, и в этой книге мы познакомим вам с самым популярным продуктом, предназначенным для автоматизации деятельности торгового предприятия – «1С Управление торговлей», которое реализовано на новейшей технологической платформе версии 1С 8.2.

Алексей Анатольевич Гладкий

Финансы / Программирование, программы, базы данных