Хитрости мультипоточочности, Максим Лысков, 2016Хитрости выведения типов. Максим Лысков. 2016
Хитрости выведения типов
Максим Лысков
Минск, 2016
Хитрости мультипоточочности, Максим Лысков, 2016Хитрости выведения типов. Максим Лысков. 2016
Знакомимся?
Максим, старший инженер-разработчик в компании EPAM Systems.
В настоящее время участвую в разработке системы иерархического
хранения и репликации данных.
Хитрости мультипоточочности, Максим Лысков, 2016Хитрости выведения типов. Максим Лысков. 2016
Хитрость №1. auto
std::map<int, std::vector<int>> m;
std::map<int, std::vector<int>>::const_iterator it = cbegin(m);
auto it2 = cbegin(m);
std::cout << std::is_same<decltype(it), decltype(it2)>::value << std::endl;
Хитрости мультипоточочности, Максим Лысков, 2016Хитрости выведения типов. Максим Лысков. 2016
Хитрость №1. auto
auto x = expression;
Реальный тип выводится из результата выражения по правилам вывода типов аргументов для шаблонной функции.
В случае {}-инициализации тип для auto – initializer_list.
auto number1 = 0; // number1 есть int
auto number2 = { 42 }; // number2 есть initializer_list<int>
Хитрости мультипоточочности, Максим Лысков, 2016Хитрости выведения типов. Максим Лысков. 2016
Хитрость №2. auto как тип возврата
template <class Left, class Right>
??? sum(Left const& l, Right const& r)
{
return l + r;
}
// C++14
template <class Left, class Right>
auto sum(Left const& l, Right const& r)
{
return l + r;
}
// C++11
template <class Left, class Right>
auto sum(Left const& l, Right const& r) -> decltype(l+r)
{
return l + r;
}
Хитрости мультипоточочности, Максим Лысков, 2016Хитрости выведения типов. Максим Лысков. 2016
Хитрость №2. auto как тип возврата
template <class Container>
auto access(Container& c)
{
Logger();
return c[0];
}
int main(void)
{
std::vector<int> v{ 1, 2, 3 };
access(v) = 42;
std::cout << v[0] << std::endl;
}
Хитрости мультипоточочности, Максим Лысков, 2016Хитрости выведения типов. Максим Лысков. 2016
Хитрость №2. auto как тип возврата
// C++14
template <class Container>
decltype(auto) access(Container& c)
{
Logger();
return c[0];
}
int main(void)
{
std::vector<int> v{ 1, 2, 3 };
access(v) = 42;
std::cout << v[0] << std::endl;
}
Хитрости мультипоточочности, Максим Лысков, 2016Хитрости выведения типов. Максим Лысков. 2016
Хитрость №3. decltype
decltype(entity)
decltype(expression)
int var;
const int&& fx();
struct A { double x; };
const A* a = new A();
int main(void)
{
decltype(var) i; // i есть int
decltype(fx()) t1 = fx(); // t1 есть const int&&
decltype(a->x) d; // d есть double
decltype((a->x)) d1 = d; // d1 есть const double&
}
Хитрости мультипоточочности, Максим Лысков, 2016Хитрости выведения типов. Максим Лысков. 2016
Хитрость №3. decltype
class SomeType
{
public:
SomeType(int);
AnotherType getValue();
};
int main(void)
{
// decltype(SomeType().getValue()) value; // oшибка компиляции
decltype(std::declval<SomeType>().getValue()) value;
}
Хитрости мультипоточочности, Максим Лысков, 2016Хитрости выведения типов. Максим Лысков. 2016
Хитрость №4. Вывод типов.
template <class T> void func(ParamType t);
func(expr);
1) ParamType ссылка
2) ParamType указатель
3) ParamType не ссылка и не указатель
4) ParamType универсальная ссылка
Хитрости мультипоточочности, Максим Лысков, 2016Хитрости выведения типов. Максим Лысков. 2016
Хитрость №4. Вывод типов.
1) ParamType ссылочный тип
template <class T> void func(T& t);
SomeType p;
func(p); // T – SomeType; t – SomeType&
SomeType const& r = p;
func(r); // T – const SomeType; t – const SomeType&
template <class T> void func(T const& t);
SomeType p;
func(p); // T – SomeType; t – SomeType const&
SomeType const& r = p;
func(r); // T – SomeType; t – const SomeType&
Хитрости мультипоточочности, Максим Лысков, 2016Хитрости выведения типов. Максим Лысков. 2016
Хитрость №4. Вывод типов.
2) ParamType указатель
template <class T> void func(T* t);
SomeType p;
func(&p); // T – SomeType; t – SomeType*
const SomeType* cp = &p;
func(cp); // T – const SomeType; t – const SomeType*
Хитрости мультипоточочности, Максим Лысков, 2016Хитрости выведения типов. Максим Лысков. 2016
Хитрость №4. Вывод типов.
3) ParamType не указатель и не ссылка
template <class T> void func(T t);
const SomeType p;
func(p); // T – SomeType; t – SomeType
Хитрости мультипоточочности, Максим Лысков, 2016Хитрости выведения типов. Максим Лысков. 2016
Хитрость №4. Вывод типов.
4) ParamType универсальная ссылка
template <class T> void func(T&& t);
SomeType p;
func(p); // T – SomeType&; t – SomeType&
const SomeType cp;
func(cp); // T – const SomeType&; t – const SomeType&
const SomeType& r = p;
func(cp); // T – const SomeType&; t – const SomeType&
func(SomeType{}); // T – SomeType; t - SomeType&&
Хитрости мультипоточочности, Максим Лысков, 2016Хитрости выведения типов. Максим Лысков. 2016
Хитрость №5. Склейка ссылок.
В результате выведения типов шаблона или в результате using alias может получиться ссылка на ссылку.
В таком случае происходит склейка ссылок
T& & == T&
T& && == T&
T&& & == T&
T&& && == T&&
using lref = SomeType&;
SomeType value;
lref& r = value; // r - SomeType&
Хитрости мультипоточочности, Максим Лысков, 2016Хитрости выведения типов. Максим Лысков. 2016
Хитрость №6. type_traits
#include <type_traits>
Информация о типе - общий вид
template <class T>
struct is_xxx
{
bool value; // true, если тип T есть XXX
}
Хитрости мультипоточочности, Максим Лысков, 2016Хитрости выведения типов. Максим Лысков. 2016
Хитрость №6. type_traits
is_void
is_integral
is_floating_point
is_array
is_enum
is_union
is_class
is_function
is_pointer
is_lvalue_reference
is_rvalue_reference
is_member_object_pointer
is_member_function_pointer
Хитрости мультипоточочности, Максим Лысков, 2016Хитрости выведения типов. Максим Лысков. 2016
Хитрость №6. type_traits
class MyType {};
template <class T> void print_info(T&& param) {
std::string const_prefix = std::is_const<decltype(param)>::value ? "const " : "";
std::string ref_suffix = std::is_lvalue_reference<decltype(param)>::value ? "& " : "";
std::string uref_suffix = std::is_rvalue_reference<decltype(param)>::value ? "&& " : "";
std::cout << "type: " << (std::is_const<T>::value ? "const " : "") << typeid(T).name()
<< (std::is_lvalue_reference<T>::value ? "& " : "")
<< (std::is_rvalue_reference<T>::value ? "&& " : "") << std::endl;
std::cout << "param: " << const_prefix << typeid(param).name() << ref_suffix << uref_suffix << std::endl;
}
int main(void) {
MyType t;
print_info(t);
print_info(std::move(t));
}
type: class MyType&
param: class MyType&
type: class MyType
param: class MyType&&
Хитрости мультипоточочности, Максим Лысков, 2016Хитрости выведения типов. Максим Лысков. 2016
?
Хитрости мультипоточочности, Максим Лысков, 2016Хитрости выведения типов. Максим Лысков. 2016
Спасибо!

хитрости выведения типов

  • 1.
    Хитрости мультипоточочности, МаксимЛысков, 2016Хитрости выведения типов. Максим Лысков. 2016 Хитрости выведения типов Максим Лысков Минск, 2016
  • 2.
    Хитрости мультипоточочности, МаксимЛысков, 2016Хитрости выведения типов. Максим Лысков. 2016 Знакомимся? Максим, старший инженер-разработчик в компании EPAM Systems. В настоящее время участвую в разработке системы иерархического хранения и репликации данных.
  • 3.
    Хитрости мультипоточочности, МаксимЛысков, 2016Хитрости выведения типов. Максим Лысков. 2016 Хитрость №1. auto std::map<int, std::vector<int>> m; std::map<int, std::vector<int>>::const_iterator it = cbegin(m); auto it2 = cbegin(m); std::cout << std::is_same<decltype(it), decltype(it2)>::value << std::endl;
  • 4.
    Хитрости мультипоточочности, МаксимЛысков, 2016Хитрости выведения типов. Максим Лысков. 2016 Хитрость №1. auto auto x = expression; Реальный тип выводится из результата выражения по правилам вывода типов аргументов для шаблонной функции. В случае {}-инициализации тип для auto – initializer_list. auto number1 = 0; // number1 есть int auto number2 = { 42 }; // number2 есть initializer_list<int>
  • 5.
    Хитрости мультипоточочности, МаксимЛысков, 2016Хитрости выведения типов. Максим Лысков. 2016 Хитрость №2. auto как тип возврата template <class Left, class Right> ??? sum(Left const& l, Right const& r) { return l + r; } // C++14 template <class Left, class Right> auto sum(Left const& l, Right const& r) { return l + r; } // C++11 template <class Left, class Right> auto sum(Left const& l, Right const& r) -> decltype(l+r) { return l + r; }
  • 6.
    Хитрости мультипоточочности, МаксимЛысков, 2016Хитрости выведения типов. Максим Лысков. 2016 Хитрость №2. auto как тип возврата template <class Container> auto access(Container& c) { Logger(); return c[0]; } int main(void) { std::vector<int> v{ 1, 2, 3 }; access(v) = 42; std::cout << v[0] << std::endl; }
  • 7.
    Хитрости мультипоточочности, МаксимЛысков, 2016Хитрости выведения типов. Максим Лысков. 2016 Хитрость №2. auto как тип возврата // C++14 template <class Container> decltype(auto) access(Container& c) { Logger(); return c[0]; } int main(void) { std::vector<int> v{ 1, 2, 3 }; access(v) = 42; std::cout << v[0] << std::endl; }
  • 8.
    Хитрости мультипоточочности, МаксимЛысков, 2016Хитрости выведения типов. Максим Лысков. 2016 Хитрость №3. decltype decltype(entity) decltype(expression) int var; const int&& fx(); struct A { double x; }; const A* a = new A(); int main(void) { decltype(var) i; // i есть int decltype(fx()) t1 = fx(); // t1 есть const int&& decltype(a->x) d; // d есть double decltype((a->x)) d1 = d; // d1 есть const double& }
  • 9.
    Хитрости мультипоточочности, МаксимЛысков, 2016Хитрости выведения типов. Максим Лысков. 2016 Хитрость №3. decltype class SomeType { public: SomeType(int); AnotherType getValue(); }; int main(void) { // decltype(SomeType().getValue()) value; // oшибка компиляции decltype(std::declval<SomeType>().getValue()) value; }
  • 10.
    Хитрости мультипоточочности, МаксимЛысков, 2016Хитрости выведения типов. Максим Лысков. 2016 Хитрость №4. Вывод типов. template <class T> void func(ParamType t); func(expr); 1) ParamType ссылка 2) ParamType указатель 3) ParamType не ссылка и не указатель 4) ParamType универсальная ссылка
  • 11.
    Хитрости мультипоточочности, МаксимЛысков, 2016Хитрости выведения типов. Максим Лысков. 2016 Хитрость №4. Вывод типов. 1) ParamType ссылочный тип template <class T> void func(T& t); SomeType p; func(p); // T – SomeType; t – SomeType& SomeType const& r = p; func(r); // T – const SomeType; t – const SomeType& template <class T> void func(T const& t); SomeType p; func(p); // T – SomeType; t – SomeType const& SomeType const& r = p; func(r); // T – SomeType; t – const SomeType&
  • 12.
    Хитрости мультипоточочности, МаксимЛысков, 2016Хитрости выведения типов. Максим Лысков. 2016 Хитрость №4. Вывод типов. 2) ParamType указатель template <class T> void func(T* t); SomeType p; func(&p); // T – SomeType; t – SomeType* const SomeType* cp = &p; func(cp); // T – const SomeType; t – const SomeType*
  • 13.
    Хитрости мультипоточочности, МаксимЛысков, 2016Хитрости выведения типов. Максим Лысков. 2016 Хитрость №4. Вывод типов. 3) ParamType не указатель и не ссылка template <class T> void func(T t); const SomeType p; func(p); // T – SomeType; t – SomeType
  • 14.
    Хитрости мультипоточочности, МаксимЛысков, 2016Хитрости выведения типов. Максим Лысков. 2016 Хитрость №4. Вывод типов. 4) ParamType универсальная ссылка template <class T> void func(T&& t); SomeType p; func(p); // T – SomeType&; t – SomeType& const SomeType cp; func(cp); // T – const SomeType&; t – const SomeType& const SomeType& r = p; func(cp); // T – const SomeType&; t – const SomeType& func(SomeType{}); // T – SomeType; t - SomeType&&
  • 15.
    Хитрости мультипоточочности, МаксимЛысков, 2016Хитрости выведения типов. Максим Лысков. 2016 Хитрость №5. Склейка ссылок. В результате выведения типов шаблона или в результате using alias может получиться ссылка на ссылку. В таком случае происходит склейка ссылок T& & == T& T& && == T& T&& & == T& T&& && == T&& using lref = SomeType&; SomeType value; lref& r = value; // r - SomeType&
  • 16.
    Хитрости мультипоточочности, МаксимЛысков, 2016Хитрости выведения типов. Максим Лысков. 2016 Хитрость №6. type_traits #include <type_traits> Информация о типе - общий вид template <class T> struct is_xxx { bool value; // true, если тип T есть XXX }
  • 17.
    Хитрости мультипоточочности, МаксимЛысков, 2016Хитрости выведения типов. Максим Лысков. 2016 Хитрость №6. type_traits is_void is_integral is_floating_point is_array is_enum is_union is_class is_function is_pointer is_lvalue_reference is_rvalue_reference is_member_object_pointer is_member_function_pointer
  • 18.
    Хитрости мультипоточочности, МаксимЛысков, 2016Хитрости выведения типов. Максим Лысков. 2016 Хитрость №6. type_traits class MyType {}; template <class T> void print_info(T&& param) { std::string const_prefix = std::is_const<decltype(param)>::value ? "const " : ""; std::string ref_suffix = std::is_lvalue_reference<decltype(param)>::value ? "& " : ""; std::string uref_suffix = std::is_rvalue_reference<decltype(param)>::value ? "&& " : ""; std::cout << "type: " << (std::is_const<T>::value ? "const " : "") << typeid(T).name() << (std::is_lvalue_reference<T>::value ? "& " : "") << (std::is_rvalue_reference<T>::value ? "&& " : "") << std::endl; std::cout << "param: " << const_prefix << typeid(param).name() << ref_suffix << uref_suffix << std::endl; } int main(void) { MyType t; print_info(t); print_info(std::move(t)); } type: class MyType& param: class MyType& type: class MyType param: class MyType&&
  • 19.
    Хитрости мультипоточочности, МаксимЛысков, 2016Хитрости выведения типов. Максим Лысков. 2016 ?
  • 20.
    Хитрости мультипоточочности, МаксимЛысков, 2016Хитрости выведения типов. Максим Лысков. 2016 Спасибо!