2013-08-22 1 views
3

Это простой Progs шаблона, который я написал для изучения C++:неявного преобразования от истинного значения для STD :: true_type

#include <type_traits> 
#include <iostream> 

using namespace std; 

template<typename T> 
T foo(T t, true_type) 
{ 
    cout << t << " is integral! "; 
    return 2 * t; 
} 


template<typename T> 
T foo(T t, false_type) 
{ 
    cout << t << " ain't integral! "; 
    return -1 * (int)t; 
} 

template<typename T> 
T do_foo(T t){ 
    return foo(t, is_integral<T>()); 
} 

int main() 
{ 
    cout << do_foo<int>(3) << endl; 
    cout << do_foo<float>(2.5) << endl; 
} 

Он не делает ничего, чтобы фантазии, но это компилировать и работать.

Мне интересно, как работает часть is_integral<T>()?

Я читал это: http://en.cppreference.com/w/cpp/types/is_integral и я не могу найти какого-либо конкретного описания такого поведения - не определение operator()

+1

Это не вызов 'operator()', он создает временную, как 'int()'. – jrok

ответ

7

is_integral<T> тип, который наследует либо из true_type или false_type.

is_integral<T>() - вызов конструктора, так что экземпляр одного из этих типов является аргументом для вызова foo. Затем выбирается перегрузка, согласно которой она есть.

+1

Примечание: во избежание путаницы в C++ 11 это может быть 'is_integral {}'. –

+0

@ MatthieuM. любой указатель, почему они добавили эту новую нотацию? Обозначения '()' скорее напоминают создание экземпляра, чем '{}', который выглядит как определение. – dashesy

+1

@ dashy: Среди прочего, для решения проблемы [Most Vexing Parse] (https://en.wikipedia.org/wiki/Most_vexing_parse). Это также позволило пересмотреть правила инициализации без нарушения обратной совместимости (по типам преобразований). –