0% found this document useful (0 votes)
29 views241 pages

Compile-Time Tools For Generic Programming in C++ - Abel Sinkovics - CppCon 2015

Uploaded by

alan88w
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
29 views241 pages

Compile-Time Tools For Generic Programming in C++ - Abel Sinkovics - CppCon 2015

Uploaded by

alan88w
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 241

Compile-time tools supporting generic

programming in C++

Ábel Sinkovics

Morgan Stanley
Generic programming

 ”Generic programming is a programming


paradigm for developing efficient, reusable
software libraries” http://www.generic-programming.org/
 ”Generic programming is about generalizing
software components so that they can be easily
reused in a wide variety of situations.”
http://www.boost.org/community/generic_programming.html
Generic programming

 ”Generic programming is a programming


paradigm for developing efficient, reusable
software libraries” http://www.generic-programming.org/
 ”Generic programming is about generalizing
software components so that they can be easily
reused in a wide variety of situations.”
http://www.boost.org/community/generic_programming.html

In C++ they are implemented using templates


Using templates
Using templates
template <class T>
class foo { … };

template <class U>


using bar = foo<foo<U>>;

foo<bar<int>> x;
Using templates
template <class T>
class foo { … };

template <class U>


using bar = foo<foo<U>>;

foo<bar<int>> x;
Compiler
Using templates
template <class T>
class foo { … };

template <class U>


using bar = foo<foo<U>>;

foo<bar<int>> x;
Compiler

Object
code
Using templates
template <class T>
class foo { … };

template <class U>


using bar = foo<foo<U>>;

foo<bar<int>> x;
Compiler

Object
code

Error report






Using templates
template <class T>
class foo { … };

template <class U>


using bar = foo<foo<U>>;

foo<bar<int>> x;
Compiler

Object
code

Error report






Using templates
template <class T>
class foo { … };

template <class U>


using bar = foo<foo<U>>;

foo<bar<int>> x;
Compiler

Object
code

Error report






Using templates
template <class T>
class foo { … };

template <class U>


using bar = foo<foo<U>>;

foo<bar<int>> x;
Compiler

Object
code

Error report






Using templates
template <class T>
class foo { … };

template <class U>


using bar = foo<foo<U>>;

foo<bar<int>> x;
Compiler

Object
code

Error report






Using templates
template <class T>
class foo { … };

template <class U>


using bar = foo<foo<U>>;

foo<bar<int>> x;
Compiler

Object
code

Error report






Using templates
template <class T>
class foo { … };

template <class U>


using bar = foo<foo<U>>;

foo<bar<int>> x;
Compiler

Object
code

Error report






Using templates
template <class T>
class foo { … };

template <class U>


using bar = foo<foo<U>>;

foo<bar<int>> x;

template
Compiler Compiler

foo<bar<int>>
template Object
code

Error report






Template metaprogrammers

 They are using templates heavily


Template metaprogrammers

 They are using templates heavily


Compiler
 Generic library usage template

foo<bar<int>>
template
Template metaprogrammers

 They are using templates heavily


Compiler
 Generic library usage template

foo<bar<int>>
template

 Template metaprogram template Compiler


template template
template
template
template template

template

template

template template

template
template template
Template metaprogrammers

 Recently: advanced tools for template


metaprogrammers
 Templight
 Metashell + MDB
Template metaprogrammers

 Recently: advanced tools for template


metaprogrammers
 Templight
 Metashell + MDB
 Can those tools be useful for generic library
development and usage?
Available tools

 The compiler
 Error messages
 Type pretty-printing
 IDEs
 Runtime debuggers
Available tools

 The compiler
 Error messages
 Type pretty-printing
 IDEs
 Runtime debuggers
 Template metaprogrammer tools
 Metashell (with MDB)
 Templight
What is the type of...?

#include <a.hpp>

int main()
{
a<int>::handle x;
return 0;
}
What is the type of...?

#include <a.hpp>

int main()
{
a<int>::handle x;
return 0;
}
What is the type of...?
a.hpp
#ifndef A_HPP
#define A_HPP

#include "b.hpp"

template <class T>


#include <a.hpp>
class a : public b<T, int>
int main() {
{ };
a<int>::handle x;
return 0; #endif
}
What is the type of...?
a.hpp
#ifndef A_HPP
#define A_HPP

#include "b.hpp"
b.hpp
#ifndef B_HPP template <class T>
#include <a.hpp>
#define B_HPP class a : public b<T, int>
int main() {
#include "c.hpp" { };
#include "d.hpp" a<int>::handle x;
return 0; #endif
}
template <class T, class U>
class b
{
public:
typedef typename c<T, d<U>>::handle handle;
};

#endif
What is the type of...?
a.hpp
#ifndef A_HPP
#define A_HPP
c.hpp
#ifndef C_HPP #include "b.hpp"
#define C_HPP b.hpp
#ifndef B_HPP template <class T>
#include "a.hpp"
#includeB_HPP
#define "c_factory.hpp" class a : public b<T, int>
int main() {
template "c.hpp"
#include <class T, class
{ U> };
class c "d.hpp"
#include a<int>::handle x;
{ return 0; #endif
public: <class T, class
template } U>
typedef
class b typename c_factory<typename U::item>::handle handle;
{};
public:
#endif
typedef typename c<T, d<U>>::handle handle;
};

#endif
What is the type of...?
a.hpp
#ifndef A_HPP
#define A_HPP
c.hpp
#ifndef C_HPP #include "b.hpp"
#define C_HPP a<int>::handle
b.hpp
#ifndef B_HPP b<int,#include
int>::handle template <class T>
"a.hpp"
#includeB_HPP
#define "c_factory.hpp" class a : public b<T, int>
c<int,int
d<int>>::handle
main() {
#include <class c_factory<d<int>::item>::handle
template "c.hpp" T, class
{ U> };
class c "d.hpp"
#include a<int>::handle x;
...
{ return 0; #endif
public: <class T, class
template } U>
typedef
class b typename c_factory<typename U::item>::handle handle;
{};
public:
#endif
typedef typename c<T, d<U>>::handle handle;
};

#endif
Approaches

 Enforced error message


 Displaying the name at runtime
 IDEs
 Debuggers
 Metaprogrammer tools
Enforced error message
Enforced error message
#include <a.hpp>

int main()
{
a<int>::handle x;
return 0;
}
Enforced error message
#include <a.hpp>

int main()
{
a<int>::handle x;

}
return 0;
Compiler
Enforced error message
#include <a.hpp>

int main()
{
a<int>::handle x;

}
return 0;
Compiler

Error report






Enforced error message
#include <a.hpp>

int main()
{
a<int>::handle x;

}
return 0;
Compiler

Error report






Enforced error message
#include <a.hpp>

int main()
{
a<int>::handle x;

}
return 0;
Compiler

Error report



g<int>


boost::mpl::print
int main()
{
boost::mpl::print< a<int>::handle > t;
}
boost::mpl::print
int main()
{
boost::mpl::print< a<int>::handle > t;
} Clang
In file included from main1_err.cpp:3:
boost/mpl/print.hpp:50:23: warning: division by zero is undefined
[-Wdivision-by-zero]
const int m_x = 1 / (sizeof(T) - sizeof(T));
^ ~~~~~~~~~~~~~~~~~~~~~~~
main1_err.cpp:7:39: note: in instantiation of template class
'boost::mpl::print<g<int> >' requested here
boost::mpl::print< a<int>::handle > t;
^
1 warning generated.
boost::mpl::print
int main()
{
boost::mpl::print< a<int>::handle > t;
} Clang
In file included from main1_err.cpp:3:
boost/mpl/print.hpp:50:23: warning: division by zero is undefined
[-Wdivision-by-zero]
const int m_x = 1 / (sizeof(T) - sizeof(T));
^ ~~~~~~~~~~~~~~~~~~~~~~~
main1_err.cpp:7:39: note: in instantiation of template class
'boost::mpl::print<g<int> >' requested here
boost::mpl::print< a<int>::handle > t;
^
1 warning generated.
boost::mpl::print
int main()
{
boost::mpl::print< a<int>::handle > t;
} Clang
In file included from main1_err.cpp:3:
boost/mpl/print.hpp:50:23: warning: division by zero is undefined
[-Wdivision-by-zero]
const int m_x = 1 / (sizeof(T) - sizeof(T));
^ ~~~~~~~~~~~~~~~~~~~~~~~
Visual class
main1_err.cpp:7:39: note: in instantiation of template C++
'boost::mpl::print<g<int> >' requested here
boost::mpl::print< error
boost/mpl/print.hpp(52): a<int>::handle > t; integral constant
C4308: negative
converted to unsigned type ^
1 warning generated.
main.cpp(7) : see reference to class template instanti
ation 'boost::mpl::print<g<T>>' being compiled
with
[
T=int
]
boost::mpl::print
int main()
{
boost::mpl::print< a<int>::handle > t;
} Clang
In file included from main1_err.cpp:3:
boost/mpl/print.hpp:50:23: warning: division by zero is undefined
[-Wdivision-by-zero]
const int m_x = 1 / (sizeof(T) - sizeof(T));
^ ~~~~~~~~~~~~~~~~~~~~~~~
Visual class
main1_err.cpp:7:39: note: in instantiation of template C++
'boost::mpl::print<g<int> >' requested here
boost::mpl::print< error
boost/mpl/print.hpp(52): a<int>::handle > t; integral constant
C4308: negative
converted to unsigned type ^
1 warning generated.
main.cpp(7) : see reference to class template instanti
ation 'boost::mpl::print<g<T>>' being compiled
with
[
T=int
]
boost::mpl::print
int main()
{
boost::mpl::print< a<int>::handle > t;
} Clang
In file included from main1_err.cpp:3:
boost/mpl/print.hpp:50:23: warning: division by zero is undefined
[-Wdivision-by-zero]
const int m_x = 1 / (sizeof(T) - sizeof(T));
^ ~~~~~~~~~~~~~~~~~~~~~~~
Visual class
main1_err.cpp:7:39: note: in instantiation of template C++
'boost::mpl::print<g<int> >' requested here
boost::mpl::print< error
boost/mpl/print.hpp(52): a<int>::handle > t; integral constant
C4308: negative
converted to unsigned type ^
1 warning generated.
main.cpp(7) : see reference to class template instanti
ation 'boost::mpl::print<g<T>>' being compiled
with
[
T=int
]
boost::mpl::print
int main()
{
boost::mpl::print< a<int>::handle > t;
} Clang
In file included from main1_err.cpp:3:
boost/mpl/print.hpp:50:23: warning: division by zero is undefined
[-Wdivision-by-zero]
const int m_x = 1 / (sizeof(T) - sizeof(T));
^ ~~~~~~~~~~~~~~~~~~~~~~~
Visual class
main1_err.cpp:7:39: note: in instantiation of template C++
'boost::mpl::print<g<int> >' requested here
boost::mpl::print< error
boost/mpl/print.hpp(52): a<int>::handle > t; integral constant
C4308: negative
converted to unsigned type ^
1 warning generated.
main.cpp(7) : see reference to class template instanti
ation 'boost::mpl::print<g<T>>' being compiled
with
[
T=int
]
metamonad::fail_with_type
int main()
{
mpllibs::metamonad::fail_with_type< a<int>::handle >();
}
metamonad::fail_with_type
int main()
{
mpllibs::metamonad::fail_with_type< a<int>::handle >();
} GCC
metamonad/fail_with_type.hpp:9:0,
from main1_err_mpllibs.cpp:3:
metamonad/v1/fail_with_type.hpp: In instantiation of ‘void mpllibs::metamonad::
v1::fail_with_type() [with T = g<int>]’:
main1_err_mpllibs.cpp:7:56: required from here
metamonad/v1/fail_with_type.hpp:26:70: error: ‘f’ is not a member of ‘mpllibs::
metamonad::v1::impl::FAIL_WITH_TYPE__________________________________<g<int> >’
impl::FAIL_WITH_TYPE__________________________________<T>::f();
^
metamonad::fail_with_type
int main()
{
mpllibs::metamonad::fail_with_type< a<int>::handle >();
} GCC
metamonad/fail_with_type.hpp:9:0,
from main1_err_mpllibs.cpp:3:
metamonad/v1/fail_with_type.hpp: In instantiation of ‘void mpllibs::metamonad::
v1::fail_with_type() [with T = g<int>]’:
main1_err_mpllibs.cpp:7:56: required from here
metamonad/v1/fail_with_type.hpp:26:70: error: ‘f’ is not a member of ‘mpllibs::
metamonad::v1::impl::FAIL_WITH_TYPE__________________________________<g<int> >’
impl::FAIL_WITH_TYPE__________________________________<T>::f();
^
metamonad::fail_with_type
int main()
{
mpllibs::metamonad::fail_with_type< a<int>::handle >();
} GCC
metamonad/fail_with_type.hpp:9:0,
from main1_err_mpllibs.cpp:3: Clang
metamonad/v1/fail_with_type.hpp: In instantiation
In file included from main1_err_mpllibs.cpp:3: of ‘void mpllibs::metamonad::
v1::fail_with_type()
In file included from [with T = g<int>]’:
metamonad/fail_with_type.hpp:9:
main1_err_mpllibs.cpp:7:56: required error:
metamonad/v1/fail_with_type.hpp:26:68: from here
no member
error: ‘f’ is not a member of ‘mpllibs::
named 'f' in 'mpllibs::metamonad::v1::impl::FAIL_WITH_TYPE________________
metamonad/v1/fail_with_type.hpp:26:70:
__________________<g<int> >'
metamonad::v1::impl::FAIL_WITH_TYPE__________________________________<g<int> >’
impl::FAIL_WITH_TYPE__________________________________<T>::f();
impl::FAIL_WITH_TYPE__________________________________<T>::f();
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^ ^
main1_err_mpllibs.cpp:7:23: note: in instantiation of function template
specialization 'mpllibs::metamonad::v1::fail_with_type<g<int> >' requested
here
mpllibs::metamonad::fail_with_type< a<int>::handle >();
^
1 error generated.
metamonad::fail_with_type
int main()
{
mpllibs::metamonad::fail_with_type< a<int>::handle >();
} GCC
metamonad/fail_with_type.hpp:9:0,
from main1_err_mpllibs.cpp:3: Clang
metamonad/v1/fail_with_type.hpp: In instantiation
In file included from main1_err_mpllibs.cpp:3: of ‘void mpllibs::metamonad::
v1::fail_with_type()
In file included from [with T = g<int>]’:
metamonad/fail_with_type.hpp:9:
main1_err_mpllibs.cpp:7:56: required error:
metamonad/v1/fail_with_type.hpp:26:68: from here
no member
error: ‘f’ is not a member of ‘mpllibs::
named 'f' in 'mpllibs::metamonad::v1::impl::FAIL_WITH_TYPE________________
metamonad/v1/fail_with_type.hpp:26:70:
__________________<g<int> >'
metamonad::v1::impl::FAIL_WITH_TYPE__________________________________<g<int> >’
impl::FAIL_WITH_TYPE__________________________________<T>::f();
impl::FAIL_WITH_TYPE__________________________________<T>::f();
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^ ^
main1_err_mpllibs.cpp:7:23: note: in instantiation of function template
specialization 'mpllibs::metamonad::v1::fail_with_type<g<int> >' requested
here
mpllibs::metamonad::fail_with_type< a<int>::handle >();
^
1 error generated.
metamonad::fail_with_type
int main()
{
mpllibs::metamonad::fail_with_type< a<int>::handle >();
} GCC
metamonad/fail_with_type.hpp:9:0,
from main1_err_mpllibs.cpp:3: Clang
metamonad/v1/fail_with_type.hpp: In instantiation
In file included from main1_err_mpllibs.cpp:3: of ‘void mpllibs::metamonad::
v1::fail_with_type()
In file included from [with T = g<int>]’:
metamonad/fail_with_type.hpp:9:
main1_err_mpllibs.cpp:7:56: required error:
from here
Visual C++
metamonad/v1/fail_with_type.hpp:26:68: no member
metamonad\v1\fail_with_type.hpp(26): error C2039:
error: 'f'not
‘f’ is : is
a not a member
member of
named 'f' in 'mpllibs::metamonad::v1::impl::FAIL_WITH_TYPE________________
metamonad/v1/fail_with_type.hpp:26:70: of ‘mpllibs::
'mpllibs::metamonad::v1::impl::FAIL_WITH_TYPE_____________________________
__________________<g<int> >'
metamonad::v1::impl::FAIL_WITH_TYPE__________________________________<g<int> >’
_____<T>'
impl::FAIL_WITH_TYPE__________________________________<T>::f();
impl::FAIL_WITH_TYPE__________________________________<T>::f();
with
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^ ^
[
main1_err_mpllibs.cpp:7:23: note: in instantiation of function template
T=g<int>
specialization 'mpllibs::metamonad::v1::fail_with_type<g<int> >' requested
here ]
main.cpp(7) : see reference a<int>::handle
mpllibs::metamonad::fail_with_type< to function template
>(); instantiation '
void mpllibs::metamonad::v1::fail_with_type<g<T>>(void)'
^ being compiled
with
1 error generated.
[
T=int
]
metamonad::fail_with_type
int main()
{
mpllibs::metamonad::fail_with_type< a<int>::handle >();
} GCC
metamonad/fail_with_type.hpp:9:0,
from main1_err_mpllibs.cpp:3: Clang
metamonad/v1/fail_with_type.hpp: In instantiation
In file included from main1_err_mpllibs.cpp:3: of ‘void mpllibs::metamonad::
v1::fail_with_type()
In file included from [with T = g<int>]’:
metamonad/fail_with_type.hpp:9:
main1_err_mpllibs.cpp:7:56: required error:
from here
Visual C++
metamonad/v1/fail_with_type.hpp:26:68: no member
metamonad\v1\fail_with_type.hpp(26): error C2039:
error: 'f'not
‘f’ is : is
a not a member
member of
named 'f' in 'mpllibs::metamonad::v1::impl::FAIL_WITH_TYPE________________
metamonad/v1/fail_with_type.hpp:26:70: of ‘mpllibs::
'mpllibs::metamonad::v1::impl::FAIL_WITH_TYPE_____________________________
__________________<g<int> >'
metamonad::v1::impl::FAIL_WITH_TYPE__________________________________<g<int> >’
_____<T>'
impl::FAIL_WITH_TYPE__________________________________<T>::f();
impl::FAIL_WITH_TYPE__________________________________<T>::f();
with
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^ ^
[
main1_err_mpllibs.cpp:7:23: note: in instantiation of function template
T=g<int>
specialization 'mpllibs::metamonad::v1::fail_with_type<g<int> >' requested
here ]
main.cpp(7) : see reference a<int>::handle
mpllibs::metamonad::fail_with_type< to function template
>(); instantiation '
void mpllibs::metamonad::v1::fail_with_type<g<T>>(void)'
^ being compiled
with
1 error generated.
[
T=int
]
Displaying the name at runtime
Displaying the name at runtime
#include <a.hpp>

int main()
{
a<int>::handle x;
return 0;
}
Displaying the name at runtime
#include <a.hpp>

int main()
{
a<int>::handle x;

}
return 0;
Compiler
Displaying the name at runtime
#include <a.hpp>

int main()
{
a<int>::handle x;

}
return 0;
Compiler

Object
code
Displaying the name at runtime
#include <a.hpp>

int main()
{
a<int>::handle x;

}
return 0;
Compiler

Object
code

Executable
Displaying the name at runtime
#include <a.hpp>

int main()
{
a<int>::handle x;

}
return 0;
Compiler

Object
code

Executable
Standard output

g<int>
Displaying the name at runtime
#include <a.hpp>

int main()
{
a<int>::handle x;

}
return 0;
Compiler

Object
code

Executable
Standard output

g<int>
Displaying the name at runtime

int main()
{
std::cout << typeid(a<int>::handle).name();
}
Displaying the name at runtime

int main()
{
std::cout << typeid(a<int>::handle).name();
}

 Gcc: 1gIiE
 Clang: 1gIiE
Displaying the name at runtime

int main()
{
std::cout << typeid(a<int>::handle).name();
}

 Gcc: 1gIiE c++filt


g<int>
 Clang: 1gIiE
Displaying the name at runtime

int main()
{
std::cout << typeid(a<int>::handle).name();
}

 Gcc: 1gIiE c++filt


g<int>
 Clang: 1gIiE
 Visual C++ : class g<int>
Displaying the name at runtime

 Boost.TypeIndex

int main()
{
using boost::typeindex::type_id_with_cvr;
std::cout
<<
<< std::endl;
}
Displaying the name at runtime

 Boost.TypeIndex

int main()
{
using boost::typeindex::type_id_with_cvr;
std::cout
<< type_id_with_cvr< >()
<< std::endl;
}
Displaying the name at runtime

 Boost.TypeIndex

int main()
{
using boost::typeindex::type_id_with_cvr;
std::cout
<< type_id_with_cvr<a<int>::handle>()
<< std::endl;
}
Displaying the name at runtime

 Boost.TypeIndex

int main()
{
using boost::typeindex::type_id_with_cvr;
std::cout
<< type_id_with_cvr<a<int>::handle>().pretty_name()
<< std::endl;
}
Displaying the name at runtime

 Boost.TypeIndex

int main()
{
using boost::typeindex::type_id_with_cvr;
std::cout
<< type_id_with_cvr<a<int>::handle>().pretty_name()
<< std::endl;
}

g<int>
Displaying the name at runtime

 Boost.TypeIndex

int main()
{
using boost::typeindex::type_id_with_cvr;
std::cout
<< type_id_with_cvr<a<int>::handle>().pretty_name()
<< std::endl;
}

Visual C++

class g<int>
IDEs

IDE
IDEs
#include <a.hpp>

int main()
{
a<int>::handle x;
return 0;
}

IDE
IDEs
#include <a.hpp>

int main()
{
a<int>::handle x;
return 0;
}

a<int>::handle

IDE
IDEs
#include <a.hpp>

int main()
{
a<int>::handle x;
return 0;
}

a<int>::handle

IDE
IDEs
#include <a.hpp>

int main()
{
a<int>::handle x;

}
return 0;
Compiler
a<int>::handle

IDE
IDEs
#include <a.hpp>

int main()
{
a<int>::handle x;

}
return 0;
Compiler
Parser

a<int>::handle

IDE
IDEs
#include <a.hpp>

int main()
{
a<int>::handle x;

}
return 0;
Compiler
Parser

a<int>::handle

b.hpp
#ifndef B_HPP
#define B_HPP

#include "c.hpp"
IDE
#include "d.hpp"

template <class T, class U>


class b
{
public:
typedef typename c<T, d<U>>::handle handle;
};

#endif
IDEs
#include <a.hpp>

int main()
{
a<int>::handle x;

}
return 0;
Compiler
Parser

a<int>::handle

b.hpp
#ifndef B_HPP
#define B_HPP

#include "c.hpp"
IDE
#include "d.hpp"

template <class T, class U>


class b
{
public:
typedef typename c<T, d<U>>::handle handle;
};

#endif
GDB
GDB
#include <a.hpp>

int main()
{
a<int>::handle x;
return 0;
}
GDB
#include <a.hpp>

int main()
{
a<int>::handle x;

}
return 0;
Compiler
GDB
#include <a.hpp>

int main()
{
a<int>::handle x;

}
return 0;
Compiler

Object
code
GDB
#include <a.hpp>

int main()
{
a<int>::handle x;

}
return 0;
Compiler

Object
code Debug
information
GDB
#include <a.hpp>

int main()
{
a<int>::handle x;

}
return 0;
Compiler

Object
code Debug
information

Executable
GDB
#include <a.hpp>

int main()
{
a<int>::handle x;

}
return 0;
Compiler

Object
code Debug
information

Executable

GDB
GDB
#include <a.hpp>

int main()
{
a<int>::handle x;

}
return 0;
Compiler

Object
code Debug
information

Executable

GDB
g<int>
GDB

$ g++ main1.cpp -g -std=c++11


$
GDB

$ g++ main1.cpp -g -std=c++11


$ gdb a.out
GDB

$ g++ main1.cpp -g -std=c++11


$ gdb a.out

(gdb)
GDB

$ g++ main1.cpp -g -std=c++11


$ gdb a.out

(gdb) break main1.cpp:5
1 #include <a.hpp>
GDB 2
3 int main()
4 {
5 a<int>::handle x;
6 return 0;
7 }
$ g++ main1.cpp -g -std=c++11
$ gdb a.out

(gdb) break main1.cpp:5
1 #include <a.hpp>
GDB 2
3 int main()
4 {
5 a<int>::handle x;
6 return 0;
7 }
$ g++ main1.cpp -g -std=c++11
$ gdb a.out

(gdb) break main1.cpp:5
Breakpoint 1 at 0x4006d1: file main1.cpp, line 5.
(gdb)
1 #include <a.hpp>
GDB 2
3 int main()
4 {
5 a<int>::handle x;
6 return 0;
7 }
$ g++ main1.cpp -g -std=c++11
$ gdb a.out

(gdb) break main1.cpp:5
Breakpoint 1 at 0x4006d1: file main1.cpp, line 5.
(gdb) run
1 #include <a.hpp>
GDB 2
3 int main()
4 {
5 a<int>::handle x;
6 return 0;
7 }
$ g++ main1.cpp -g -std=c++11
$ gdb a.out

(gdb) break main1.cpp:5
Breakpoint 1 at 0x4006d1: file main1.cpp, line 5.
(gdb) run
Starting program: a.out

Breakpoint 1, main () at main1.cpp:6


6 return 0;
(gdb)
1 #include <a.hpp>
GDB 2
3 int main()
4 {
5 a<int>::handle x;
6 return 0;
7 }
$ g++ main1.cpp -g -std=c++11
$ gdb a.out

(gdb) break main1.cpp:5
Breakpoint 1 at 0x4006d1: file main1.cpp, line 5.
(gdb) run
Starting program: a.out

Breakpoint 1, main () at main1.cpp:6


6 return 0;
(gdb) ptype x
1 #include <a.hpp>
GDB 2
3 int main()
4 {
5 a<int>::handle x;
6 return 0;
7 }
$ g++ main1.cpp -g -std=c++11
$ gdb a.out

(gdb) break main1.cpp:5
Breakpoint 1 at 0x4006d1: file main1.cpp, line 5.
(gdb) run
Starting program: a.out

Breakpoint 1, main () at main1.cpp:6


6 return 0;
(gdb) ptype x
type = class g<int> [with T = int] {
public:
void foo(void);
}
1 #include <a.hpp>
GDB 2
3 int main()
4 {
5 a<int>::handle x;
6 return 0;
7 }
$ g++ main1.cpp -g -std=c++11
$ gdb a.out

(gdb) break main1.cpp:5
Breakpoint 1 at 0x4006d1: file main1.cpp, line 5.
(gdb) run
Starting program: a.out

Breakpoint 1, main () at main1.cpp:6


6 return 0;
(gdb) ptype x
type = class g<int> [with T = int] {
public:
void foo(void);
}
Metashell

 Template metaprogramming shell & debugger


 Designed for uncovering the template
instantiation details
 Not a ”template metaprogrammer-only” shell
 http://github.com/sabel83/metashell
Metashell

Metashell
Metashell
#include <a.hpp>

int main()
{
a<int>::handle x;
return 0;
}

Metashell
Metashell
#include <a.hpp>

int main()
{
a<int>::handle x;
return 0;
}

a<int>::handle

Metashell
Metashell
#include <a.hpp>

int main()
{
a<int>::handle x;

}
return 0;
Compiler
a<int>::handle

Metashell
Metashell
#include <a.hpp>

int main()
{
a<int>::handle x;

}
return 0;
Compiler
Parser

a<int>::handle

Metashell
Metashell
#include <a.hpp>

int main()
{
a<int>::handle x;

}
return 0;
Compiler
Parser

a<int>::handle

Metashell
g<int>
Metashell

$ metashell
>
Metashell

$ metashell
> #include "main1.cpp"
>
Metashell

$ metashell
> #include "main1.cpp"
> a<int>::handle
Metashell

$ metashell
> #include "main1.cpp"
> a<int>::handle
g<int>
What is the type of...? #2

#include <a.hpp>

template <class T>


void fun()
{
typename a<T>::handle h;
h.foo();
}

int main()
{

}
What is the type of...? #2

#include <a.hpp>

template <class T>


void fun()
{
typename a<T>::handle h;
h.foo();
}

int main()
{
fun<double>();
}
What is the type of...? #2

#include <a.hpp>

template <class T>


void fun()
{
typename a<T>::handle h;
h.foo();
}

int main()
{
fun<double>();
}
Approaches

 Enforced error message


 Displaying the name at runtime
 IDEs
 Debuggers
 Metaprogrammer tools
boost::mpl::print
template <class T>
void fun()
{

typename a<T>::handle h;
h.foo();
}
boost::mpl::print
template <class T>
void fun()
{
boost::mpl::print< typename a<T>::handle > t;
typename a<T>::handle h;
h.foo();
}
boost::mpl::print
template <class T>
void fun()
{
boost::mpl::print< typename a<T>::handle > t;
typename a<T>::handle h;
h.foo();
Clang
} In file included from main2_err.cpp:3:
boost/mpl/print.hpp:50:23: warning: division by zero is undefined
[-Wdivision-by-zero]
const int m_x = 1 / (sizeof(T) - sizeof(T));
^ ~~~~~~~~~~~~~~~~~~~~~~~
main2_err.cpp:8:46: note: in instantiation of template class
'boost::mpl::print<g<int> >' requested here
boost::mpl::print< typename a<T>::handle > t;
^
main2_err.cpp:15:3: note: in instantiation of function template
specialization 'fun<double>' requested here
fun<double>();
^
1 warning generated.
boost::mpl::print
template <class T>
void fun()
{
boost::mpl::print< typename a<T>::handle > t;
typename a<T>::handle h;
h.foo();
Clang
} In file included from main2_err.cpp:3:
boost/mpl/print.hpp:50:23: warning: division by zero is undefined
[-Wdivision-by-zero]
const int m_x = 1 / (sizeof(T) - sizeof(T));
^ ~~~~~~~~~~~~~~~~~~~~~~~
main2_err.cpp:8:46: note: in instantiation of template class
'boost::mpl::print<g<int> >' requested here
boost::mpl::print< typename a<T>::handle > t;
^
main2_err.cpp:15:3: note: in instantiation of function template
specialization 'fun<double>' requested here
fun<double>();
^
1 warning generated.
boost::mpl::print
template <class T>
void fun()
{
boost::mpl::print< typename a<T>::handle > t;
typename a<T>::handle h;
h.foo();
Clang
} In file included from main2_err.cpp:3:
boost/mpl/print.hpp:50:23: warning: division by zero is undefined
[-Wdivision-by-zero]
const int m_x = 1 / (sizeof(T) - sizeof(T));Visual C++
^ ~~~~~~~~~~~~~~~~~~~~~~~
boost\mpl\print.hpp(52): error C4308: negative integral constant
main2_err.cpp:8:46:
converted to unsigned typenote: in instantiation of template class
'boost::mpl::print<g<int>
main.cpp(8) : see reference>'
torequested here instanti
class template
boost::mpl::print< typename
ation 'boost::mpl::print<g<T>>' a<T>::handle
being compiled > t;
with ^
main2_err.cpp:15:3:
[ note: in instantiation of function template
specialization
T=int 'fun<double>' requested here
fun<double>();
]
^ main.cpp(15) : see reference to function template inst
1 warning
antiation 'voidgenerated.
fun<double>(void)' being compiled
boost::mpl::print
template <class T>
void fun()
{
boost::mpl::print< typename a<T>::handle > t;
typename a<T>::handle h;
h.foo();
Clang
} In file included from main2_err.cpp:3:
boost/mpl/print.hpp:50:23: warning: division by zero is undefined
[-Wdivision-by-zero]
const int m_x = 1 / (sizeof(T) - sizeof(T));Visual C++
^ ~~~~~~~~~~~~~~~~~~~~~~~
boost\mpl\print.hpp(52): error C4308: negative integral constant
main2_err.cpp:8:46:
converted to unsigned typenote: in instantiation of template class
'boost::mpl::print<g<int>
main.cpp(8) : see reference>'
torequested here instanti
class template
boost::mpl::print< typename
ation 'boost::mpl::print<g<T>>' a<T>::handle
being compiled > t;
with ^
main2_err.cpp:15:3:
[ note: in instantiation of function template
specialization
T=int 'fun<double>' requested here
fun<double>();
]
^ main.cpp(15) : see reference to function template inst
1 warning
antiation 'voidgenerated.
fun<double>(void)' being compiled
metamonad::fail_with_type
template <class T>
void fun()
{

typename a<T>::handle h;
h.foo();
}
metamonad::fail_with_type
template <class T>
void fun()
{
mpllibs::metamonad::fail_with_type< typename a<T>::handle >();
typename a<T>::handle h;
h.foo();
}
metamonad::fail_with_type
template <class T>
void fun() GCC
In
{ file included from metamonad/fail_with_type.hpp:9:0,
from main2_err_mpllibs.cpp:3:
mpllibs::metamonad::fail_with_type< typename a<T>::handle >();
metamonad/v1/fail_with_type.hpp: In instantiation of ‘void mpllibs::
typename a<T>::handle h;
metamonad::v1::fail_with_type() [with T = g<int>]’:
h.foo();
main2_err_mpllibs.cpp:8:63: required from ‘void fun() [with T =
}
double]’
main2_err_mpllibs.cpp:15:15: required from here
metamonad/v1/fail_with_type.hpp:26:70: error: ‘f’ is not a member of
‘mpllibs::metamonad::v1::impl::FAIL_WITH_TYPE___________________________
_______<g<int> >’
impl::FAIL_WITH_TYPE__________________________________<T>::f();
^
metamonad::fail_with_type
template <class T>
void fun() GCC
In
{ file included from metamonad/fail_with_type.hpp:9:0,
from main2_err_mpllibs.cpp:3:
mpllibs::metamonad::fail_with_type< typename a<T>::handle >();
metamonad/v1/fail_with_type.hpp: In instantiation of ‘void mpllibs::
typename a<T>::handle h;
metamonad::v1::fail_with_type() [with T = g<int>]’:
h.foo();
main2_err_mpllibs.cpp:8:63: required from ‘void fun() [with T =
}
double]’
main2_err_mpllibs.cpp:15:15: required from here
metamonad/v1/fail_with_type.hpp:26:70: error: ‘f’ is not a member of
‘mpllibs::metamonad::v1::impl::FAIL_WITH_TYPE___________________________
_______<g<int> >’
impl::FAIL_WITH_TYPE__________________________________<T>::f();
^
metamonad::fail_with_type
template <class T>
void fun() GCC
In
{ file included from metamonad/fail_with_type.hpp:9:0, Clang
file included from
from main2_err_mpllibs.cpp:3:
Inmpllibs::metamonad::fail_with_type< typename a<T>::handle >();
main2_err_mpllibs.cpp:3:
metamonad/v1/fail_with_type.hpp:
Intypename
file included In instantiation of ‘void mpllibs::
from metamonad/fail_with_type.hpp:9:
a<T>::handle h;
metamonad::v1::fail_with_type() [with T error:
metamonad/v1/fail_with_type.hpp:26:68: = g<int>]’:
no member
h.foo();
main2_err_mpllibs.cpp:8:63: required from ‘void fun() [with T =
} named 'f' in 'mpllibs::metamonad::v1::impl::FAIL_WITH_TYPE_______
double]’
___________________________<g<int> >'
main2_err_mpllibs.cpp:15:15: required from here
Impl::FAIL_WITH_TYPE__________________________________<T>::f();
metamonad/v1/fail_with_type.hpp:26:70: error: ‘f’ is not a member of
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^
‘mpllibs::metamonad::v1::impl::FAIL_WITH_TYPE___________________________
main2_err_mpllibs.cpp:8:23: note: in instantiation of function template
_______<g<int> >’
specialization 'mpllibs::metamonad::v1::fail_with_type<g<int> >'
impl::FAIL_WITH_TYPE__________________________________<T>::f();
requested here
mpllibs::metamonad::fail_with_type< typename a<T>::handle >(); ^
^
main2_err_mpllibs.cpp:15:3: note: in instantiation of function template
specialization 'fun<double>' requested here
fun<double>();
^
1 error generated.
metamonad::fail_with_type
template <class T>
void fun() GCC
In
{ file included from metamonad/fail_with_type.hpp:9:0, Clang
file included from
from main2_err_mpllibs.cpp:3:
Inmpllibs::metamonad::fail_with_type< typename a<T>::handle >();
main2_err_mpllibs.cpp:3:
metamonad/v1/fail_with_type.hpp:
Intypename
file included In instantiation of ‘void mpllibs::
from metamonad/fail_with_type.hpp:9:
a<T>::handle h;
metamonad::v1::fail_with_type() [with T error:
metamonad/v1/fail_with_type.hpp:26:68: = g<int>]’:
no member
h.foo();
main2_err_mpllibs.cpp:8:63: required from ‘void fun() [with T =
} named 'f' in 'mpllibs::metamonad::v1::impl::FAIL_WITH_TYPE_______
double]’
___________________________<g<int> >'
main2_err_mpllibs.cpp:15:15: required from here
Impl::FAIL_WITH_TYPE__________________________________<T>::f();
metamonad/v1/fail_with_type.hpp:26:70: error: ‘f’ is not a member of
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^
‘mpllibs::metamonad::v1::impl::FAIL_WITH_TYPE___________________________
main2_err_mpllibs.cpp:8:23: note: in instantiation of function template
_______<g<int> >’
specialization 'mpllibs::metamonad::v1::fail_with_type<g<int> >'
impl::FAIL_WITH_TYPE__________________________________<T>::f();
requested here
mpllibs::metamonad::fail_with_type< typename a<T>::handle >(); ^
^
main2_err_mpllibs.cpp:15:3: note: in instantiation of function template
specialization 'fun<double>' requested here
fun<double>();
^
1 error generated.
metamonad::fail_with_type
template <class T>
void fun() GCC
In
{ file included from metamonad/fail_with_type.hpp:9:0, Clang
file included from
from main2_err_mpllibs.cpp:3:
Inmpllibs::metamonad::fail_with_type< typename a<T>::handle >();
main2_err_mpllibs.cpp:3:
metamonad/v1/fail_with_type.hpp:
Intypename
file included In instantiation of ‘void Visual
from metamonad/fail_with_type.hpp:9: mpllibs::
C++
a<T>::handle h;
metamonad::v1::fail_with_type() [with T error:
metamonad/v1/fail_with_type.hpp:26:68: = g<int>]’:
no member
metamonad\v1\fail_with_type.hpp(26):
h.foo(); error C2039: 'f' : is not a member
main2_err_mpllibs.cpp:8:63:
named 'f' in required from ‘void fun() [with T =
'mpllibs::metamonad::v1::impl::FAIL_WITH_TYPE_______
of
} 'mpllibs::metamonad::v1::impl::FAIL_WITH_TYPE_______________________
double]’
___________________________<g<int> >'
___________<T>'
main2_err_mpllibs.cpp:15:15: required from here
Impl::FAIL_WITH_TYPE__________________________________<T>::f();
with
metamonad/v1/fail_with_type.hpp:26:70: error: ‘f’ is not a member of
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^
[
‘mpllibs::metamonad::v1::impl::FAIL_WITH_TYPE___________________________
main2_err_mpllibs.cpp:8:23: note: in instantiation of function template
T=g<int>
_______<g<int> >’
specialization 'mpllibs::metamonad::v1::fail_with_type<g<int> >'
]
impl::FAIL_WITH_TYPE__________________________________<T>::f();
requested main.cpp(8)
here : see reference to function template instantiatio
mpllibs::metamonad::fail_with_type< typename a<T>::handle being ^
>(); compi
n 'void mpllibs::metamonad::v1::fail_with_type<g<T>>(void)'
led ^
main2_err_mpllibs.cpp:15:3:
with note: in instantiation of function template
specialization
[ 'fun<double>' requested here
fun<double>();
T=int
^ ]
1 error generated.
main.cpp(15) : see reference to function template instantiati
on
'void fun<double>(void)' being compiled
metamonad::fail_with_type
template <class T>
void fun() GCC
In
{ file included from metamonad/fail_with_type.hpp:9:0, Clang
file included from
from main2_err_mpllibs.cpp:3:
Inmpllibs::metamonad::fail_with_type< typename a<T>::handle >();
main2_err_mpllibs.cpp:3:
metamonad/v1/fail_with_type.hpp:
Intypename
file included In instantiation of ‘void Visual
from metamonad/fail_with_type.hpp:9: mpllibs::
C++
a<T>::handle h;
metamonad::v1::fail_with_type() [with T error:
metamonad/v1/fail_with_type.hpp:26:68: = g<int>]’:
no member
metamonad\v1\fail_with_type.hpp(26):
h.foo(); error C2039: 'f' : is not a member
main2_err_mpllibs.cpp:8:63:
named 'f' in required from ‘void fun() [with T =
'mpllibs::metamonad::v1::impl::FAIL_WITH_TYPE_______
of
} 'mpllibs::metamonad::v1::impl::FAIL_WITH_TYPE_______________________
double]’
___________________________<g<int> >'
___________<T>'
main2_err_mpllibs.cpp:15:15: required from here
Impl::FAIL_WITH_TYPE__________________________________<T>::f();
with
metamonad/v1/fail_with_type.hpp:26:70: error: ‘f’ is not a member of
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^
[
‘mpllibs::metamonad::v1::impl::FAIL_WITH_TYPE___________________________
main2_err_mpllibs.cpp:8:23: note: in instantiation of function template
T=g<int>
_______<g<int> >’
specialization 'mpllibs::metamonad::v1::fail_with_type<g<int> >'
]
impl::FAIL_WITH_TYPE__________________________________<T>::f();
requested main.cpp(8)
here : see reference to function template instantiatio
mpllibs::metamonad::fail_with_type< typename a<T>::handle being ^
>(); compi
n 'void mpllibs::metamonad::v1::fail_with_type<g<T>>(void)'
led ^
main2_err_mpllibs.cpp:15:3:
with note: in instantiation of function template
specialization
[ 'fun<double>' requested here
fun<double>();
T=int
^ ]
1 error generated.
main.cpp(15) : see reference to function template instantiati
on
'void fun<double>(void)' being compiled
IDEs

#include <a.hpp>

template <class T>


void fun()
{
typename a<T>::handle h;
h.foo();
}

int main()
{
fun<double>();
}
IDEs

#include <a.hpp>

template <class T>


void fun()
{
typename a<T>::handle h;
h.foo();
}

int main()
{
fun<double>();
}
IDEs

void fun<int>()
{
a<int>::handle h;
#include <a.hpp> h.foo();
}
template <class T>
void fun()
{
typename a<T>::handle h;
h.foo();
}

int main()
{
fun<double>();
}
IDEs

void fun<int>()
{
a<int>::handle h;
#include <a.hpp> h.foo();
}
template <class T>
void fun()
{ void fun<double>()
typename a<T>::handle h; {
h.foo(); a<double>::handle h;
} h.foo();
}
int main()
{
fun<double>();
}
IDEs

void fun<int>()
{
a<int>::handle h;
#include <a.hpp> h.foo();
}
template <class T>
void fun()
{ void fun<double>()
typename a<T>::handle h; {
h.foo(); a<double>::handle h;
} h.foo();
}
int main()
{ void fun<bar>()
fun<double>(); {
} a<bar>::handle h;
h.foo();
}
IDEs

void fun<int>()
{
a<int>::handle h;
#include <a.hpp> h.foo();
}
template <class T>
void fun()
{ void fun<double>()
typename a<T>::handle h; {
h.foo(); a<double>::handle h;
} h.foo();
}
int main()
{ void fun<bar>()
fun<double>(); {
} a<bar>::handle h;
h.foo();
}
GDB

$ g++ main2.cpp -g -std=c++11


$
GDB

$ g++ main2.cpp -g -std=c++11


$ gdb a.out

(gdb)
1 #include <a.hpp>
GDB 2
3 template <class T>
4 void fun()
5 {
6 typename a<T>::handle h;
7 h.foo();
$ g++ main2.cpp -g -std=c++11
8 }
$ gdb a.out

(gdb) break main2.cpp:6
1 #include <a.hpp>
GDB 2
3 template <class T>
4 void fun()
5 {
6 typename a<T>::handle h;
7 h.foo();
$ g++ main2.cpp -g -std=c++11
8 }
$ gdb a.out

(gdb) break main2.cpp:6
Breakpoint 1 at 0x4008c7: file main2.cpp, line 6.
(gdb)
1 #include <a.hpp>
GDB 2
3 template <class T>
4 void fun()
5 {
6 typename a<T>::handle h;
7 h.foo();
$ g++ main2.cpp -g -std=c++11
8 }
$ gdb a.out

(gdb) break main2.cpp:6
Breakpoint 1 at 0x4008c7: file main2.cpp, line 6.
(gdb) run
1 #include <a.hpp>
GDB 2
3 template <class T>
4 void fun()
5 {
6 typename a<T>::handle h;
7 h.foo();
$ g++ main2.cpp -g -std=c++11
8 }
$ gdb a.out

(gdb) break main2.cpp:6
Breakpoint 1 at 0x4008c7: file main2.cpp, line 6.
(gdb) run
Starting program: a.out

Breakpoint 1, fun<double> () at main2.cpp:7


7 h.foo();
(gdb)
1 #include <a.hpp>
GDB 2
3 template <class T>
4 void fun()
5 {
6 typename a<T>::handle h;
7 h.foo();
$ g++ main2.cpp -g -std=c++11
8 }
$ gdb a.out

(gdb) break main2.cpp:6
Breakpoint 1 at 0x4008c7: file main2.cpp, line 6.
(gdb) run
Starting program: a.out

Breakpoint 1, fun<double> () at main2.cpp:7


7 h.foo();
(gdb)
1 #include <a.hpp>
GDB 2
3 template <class T>
4 void fun()
5 {
6 typename a<T>::handle h;
7 h.foo();
$ g++ main2.cpp -g -std=c++11
8 }
$ gdb a.out

(gdb) break main2.cpp:6
Breakpoint 1 at 0x4008c7: file main2.cpp, line 6.
(gdb) run
Starting program: a.out

Breakpoint 1, fun<double> () at main2.cpp:7


7 h.foo();
(gdb) ptype h
1 #include <a.hpp>
GDB 2
3 template <class T>
4 void fun()
5 {
6 typename a<T>::handle h;
7 h.foo();
$ g++ main2.cpp -g -std=c++11
8 }
$ gdb a.out

(gdb) break main2.cpp:6
Breakpoint 1 at 0x4008c7: file main2.cpp, line 6.
(gdb) run
Starting program: a.out

Breakpoint 1, fun<double> () at main2.cpp:7


7 h.foo();
(gdb) ptype h
type = class g<int> [with T = int] {
public:
void foo(void);
}
1 #include <a.hpp>
GDB 2
3 template <class T>
4 void fun()
5 {
6 typename a<T>::handle h;
7 h.foo();
$ g++ main2.cpp -g -std=c++11
8 }
$ gdb a.out

(gdb) break main2.cpp:6
Breakpoint 1 at 0x4008c7: file main2.cpp, line 6.
(gdb) run
Starting program: a.out

Breakpoint 1, fun<double> () at main2.cpp:7


7 h.foo();
(gdb) ptype h
type = class g<int> [with T = int] {
public:
void foo(void);
}
Metashell

$ metashell
>
Metashell

$ metashell
> #include "main2.cpp"
>
Metashell

$ metashell
> #include "main2.cpp"
> a<double>::handle
Metashell

$ metashell
> #include "main2.cpp"
> a<double>::handle
g<int>
>
Metashell

$ metashell
> #include "main2.cpp" Why?
> a<double>::handle
g<int>
>
Metashell

$ metashell
> #include "main2.cpp" Why?
> a<double>::handle
g<int>
> #msh mdb a<double>::handle
Metashell

$ metashell
> #include "main2.cpp" Why?
> a<double>::handle
g<int>
> #msh mdb a<double>::handle
For help, type "help".
Metaprogram started

(mdb)
Metashell

$ metashell
> #include "main2.cpp" Why?
> a<double>::handle
g<int>
> #msh mdb a<double>::handle
For help, type "help".
Metaprogram started

(mdb) ft
Metashell

$ metashell
> #include "main2.cpp" Why?
> a<double>::handle
g<int>
> #msh mdb a<double>::handle
For help, type "help".
Metaprogram started

(mdb) ft
a<double>::handle
+ a<double> (TemplateInstantiation from <stdin>:2:26)
| ` b<double, int> (TemplateInstantiation from ./a.hpp:7:18)
| ` c<double, d<int> > (TemplateInstantiation from ./b.hpp:11:20)
| + d<int> (TemplateInstantiation from ./c.hpp:10:39)
| | ` e<int> (TemplateInstantiation from ./d.hpp:10:20)
| ` c_factory<f<int> > (TemplateInstantiation from ./c.hpp:10:20)
| ` f<int> (TemplateInstantiation from ./c_factory.hpp:8:20)
` g<int> (TemplateInstantiation from <stdin>:2:46)
What is the type of...? #3

template <class T>


int f(T&& ref)
{
return 0;
}
What is the type of...? #3

template <class T>


int f(T&& ref)
{
return 0;
}

int main()
{
f(3.1415);

}
What is the type of...? #3

template <class T>


int f(T&& ref)
{
return 0;
}

int main()
{
f(3.1415);

}
What is the type of...? #3

template <class T>


int f(T&& ref)
{
return 0;
}

int main()
{
f(3.1415);
double d = 1.0;
f(d);
}
What is the type of...? #3

template <class T>


int f(T&& ref)
{
return 0;
}

int main()
{
f(3.1415);
double d = 1.0;
f(d);
}
What is the type of...? #3
Deduced types

template <class T>


int f(T&& ref)
{
return 0;
}

int main()
{
f(3.1415);
double d = 1.0;
f(d);
}
What is the type of...? #3
Deduced types

template <class T>


int f(T&& ref)
{
return 0;
}

int main()
{
f(3.1415);
double d = 1.0;
f(d);
}

Scott Meyers
Effective Modern C++: 42 Specific Ways To Improve Your Use of C++11 and C++14
Item 4
MDB

$ metashell
MDB

$ metashell
/* … */
>
MDB

$ metashell
/* … */
> template <class T> int f(T&& ref) { return 0; }
>
MDB

$ metashell
/* … */
> template <class T> int f(T&& ref) { return 0; }
> #msh mdb decltype(f(3.1415))
MDB

$ metashell
/* … */
> template <class T> int f(T&& ref) { return 0; }
> #msh mdb decltype(f(3.1415))
For help, type "help".
Metaprogram started
(mdb)
MDB

$ metashell
/* … */
> template <class T> int f(T&& ref) { return 0; }
> #msh mdb decltype(f(3.1415))
For help, type "help".
Metaprogram started
(mdb) ft
MDB

$ metashell
/* … */
> template <class T> int f(T&& ref) { return 0; }
> #msh mdb decltype(f(3.1415))
For help, type "help".
Metaprogram started
(mdb) ft
decltype(f(3.1415))
+ f<double> (TemplateInstantiation from <stdin>:2:35)
` int (NonTemplateType from <stdin>:2:48)
MDB

$ metashell
/* … */
> template <class T> int f(T&& ref) { return 0; }
> #msh mdb decltype(f(3.1415))
For help, type "help".
Metaprogram started
(mdb) ft
decltype(f(3.1415))
+ f<double> (TemplateInstantiation from <stdin>:2:35)
` int (NonTemplateType from <stdin>:2:48)
MDB

$ metashell
/* … */
> template <class T> int f(T&& ref) { return 0; }
> #msh mdb decltype(f(3.1415))
For help, type "help".
Metaprogram started
(mdb) ft
decltype(f(3.1415))
+ f<double> (TemplateInstantiation from <stdin>:2:35)
` int (NonTemplateType from <stdin>:2:48)
(mdb)
MDB

$ metashell
/* … */
> template <class T> int f(T&& ref) { return 0; }
> #msh mdb decltype(f(3.1415))
For help, type "help".
Metaprogram started
(mdb) ft
decltype(f(3.1415))
+ f<double> (TemplateInstantiation from <stdin>:2:35)
` int (NonTemplateType from <stdin>:2:48)
(mdb)
>
MDB

$ metashell
/* … */
> template <class T> int f(T&& ref) { return 0; }
> #msh mdb decltype(f(3.1415))
For help, type "help".
Metaprogram started
(mdb) ft
decltype(f(3.1415))
+ f<double> (TemplateInstantiation from <stdin>:2:35)
` int (NonTemplateType from <stdin>:2:48)
(mdb)
> double d = 1.0;
>
MDB

$ metashell
/* … */
> template <class T> int f(T&& ref) { return 0; }
> #msh mdb decltype(f(3.1415))
For help, type "help".
Metaprogram started
(mdb) ft
decltype(f(3.1415))
+ f<double> (TemplateInstantiation from <stdin>:2:35)
` int (NonTemplateType from <stdin>:2:48)
(mdb)
> double d = 1.0;
> #msh mdb decltype(f(d))
MDB

$ metashell
/* … */
> template <class T> int f(T&& ref) { return 0; }
> #msh mdb decltype(f(3.1415))
For help, type "help".
Metaprogram started
(mdb) ft
decltype(f(3.1415))
+ f<double> (TemplateInstantiation from <stdin>:2:35)
` int (NonTemplateType from <stdin>:2:48)
(mdb)
> double d = 1.0;
> #msh mdb decltype(f(d))
For help, type "help".
Metaprogram started
(mdb)
MDB

$ metashell
/* … */
> template <class T> int f(T&& ref) { return 0; }
> #msh mdb decltype(f(3.1415))
For help, type "help".
Metaprogram started
(mdb) ft
decltype(f(3.1415))
+ f<double> (TemplateInstantiation from <stdin>:2:35)
` int (NonTemplateType from <stdin>:2:48)
(mdb)
> double d = 1.0;
> #msh mdb decltype(f(d))
For help, type "help".
Metaprogram started
(mdb) ft
MDB

$ metashell
/* … */
> template <class T> int f(T&& ref) { return 0; }
> #msh mdb decltype(f(3.1415))
For help, type "help".
Metaprogram started
(mdb) ft
decltype(f(3.1415))
+ f<double> (TemplateInstantiation from <stdin>:2:35)
` int (NonTemplateType from <stdin>:2:48)
(mdb)
> double d = 1.0;
> #msh mdb decltype(f(d))
For help, type "help".
Metaprogram started
(mdb) ft
decltype(f(d))
+ f<double &> (TemplateInstantiation from <stdin>:2:35)
` int (NonTemplateType from <stdin>:2:43)
MDB

$ metashell
/* … */
> template <class T> int f(T&& ref) { return 0; }
> #msh mdb decltype(f(3.1415))
For help, type "help".
Metaprogram started
(mdb) ft
decltype(f(3.1415))
+ f<double> (TemplateInstantiation from <stdin>:2:35)
` int (NonTemplateType from <stdin>:2:48)
(mdb)
> double d = 1.0;
> #msh mdb decltype(f(d))
For help, type "help".
Metaprogram started
(mdb) ft
decltype(f(d))
+ f<double &> (TemplateInstantiation from <stdin>:2:35)
` int (NonTemplateType from <stdin>:2:43)
Templight

 Clang extension/tool
 Logs template instantion-related events
 Original: http://plc.inf.elte.hu/templight/
 Fork: https://github.com/mikael-s-persson/templight
 We will be using the fork
Templight

$ templight++ -std=c++11 -c -Xtemplight -profiler -Xtemplight -safe-mode main3.cpp


Templight

$ templight++ -std=c++11 -c -Xtemplight -profiler -Xtemplight -safe-mode main3.cpp

main3.o.trace.pbf
Templight

$ templight++ -std=c++11 -c -Xtemplight -profiler -Xtemplight -safe-mode main3.cpp

main3.o.trace.pbf

$ templight-convert -f <type> -i main3.o.trace.pbf


Templight

$ templight++ -std=c++11 -c -Xtemplight -profiler -Xtemplight -safe-mode main3.cpp

main3.o.trace.pbf

$ templight-convert -f <type> -i main3.o.trace.pbf

XML Graphml Graphviz Callgrind


Templight

$ templight++ -std=c++11 -c -Xtemplight -profiler -Xtemplight -safe-mode main3.cpp

main3.o.trace.pbf

$ templight-convert -f <type> -i main3.o.trace.pbf

XML Graphml Graphviz Callgrind


KCacheGrind

 Generate a callgrind output from Templight


 Open it with KCacheGrind
KCacheGrind

 Generate a callgrind output from Templight


 Open it with KCacheGrind

instantiates

instantiates
Understanding template
instantiations
 What happens when you instantiate a template
function?
 The body of the template function might trigger
further template instantiations
 It is often useful to understand what happens
Summarising numbers
sum.hpp
#include <type_traits>

template <class T>


T sum(T t_) { return t_; }

template <class T, class... Ts>


typename std::common_type<T, Ts...>::type
sum(T t_, Ts... ts_)
{
return t_ + sum(ts_...);
}
Summarising numbers
sum.hpp
#include <type_traits>

template <class T>


T sum(T t_) { return t_; }

template <class T, class... Ts>


typename std::common_type<T, Ts...>::type
sum(T t_, Ts... ts_)
{
return t_ + sum(ts_...);
}

sum(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
Summarising numbers
sum.hpp
#include <type_traits>

template <class T>


$ metashell
T sum(T t_) { return t_; }

template <class T, class... Ts>


typename std::common_type<T, Ts...>::type
sum(T t_, Ts... ts_)
{
return t_ + sum(ts_...);
}

sum(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
Summarising numbers
sum.hpp
#include <type_traits>

template <class T>


$ metashell
T sum(T t_) { return t_; }
/* … */
>
template <class T, class... Ts>
typename std::common_type<T, Ts...>::type
sum(T t_, Ts... ts_)
{
return t_ + sum(ts_...);
}

sum(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
Summarising numbers
sum.hpp
#include <type_traits>

template <class T>


$ metashell
T sum(T t_) { return t_; }
/* … */
> #include "sum.hpp"
>
template <class T, class... Ts>
typename std::common_type<T, Ts...>::type
sum(T t_, Ts... ts_)
{
return t_ + sum(ts_...);
}

sum(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
Summarising numbers
sum.hpp
#include <type_traits>

template <class T>


$ metashell
T sum(T t_) { return t_; }
/* … */
> #include "sum.hpp"
> #include <metashell/instantiate_expression.hpp>
> template <class T, class... Ts>
typename std::common_type<T, Ts...>::type
sum(T t_, Ts... ts_)
{
return t_ + sum(ts_...);
}

sum(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
Summarising numbers
sum.hpp
#include <type_traits>

template <class T>


$ metashell
T sum(T t_) { return t_; }
/* … */
> #include "sum.hpp"
> #include <metashell/instantiate_expression.hpp>
template <class T, class...
> METASHELL_INSTANTIATE_EXPRESSION( sum(1, 2, Ts>
3, 4, 5, 6, 7, 8, 9, 10) )
typename std::common_type<T, Ts...>::type
sum(T t_, Ts... ts_)
{
return t_ + sum(ts_...);
}

sum(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
Summarising numbers
sum.hpp
#include <type_traits>

template <class T>


$ metashell
T sum(T t_) { return t_; }
/* … */
> #include "sum.hpp"
> #include <metashell/instantiate_expression.hpp>
template <class T, class...
> METASHELL_INSTANTIATE_EXPRESSION( sum(1, 2, Ts>
3, 4, 5, 6, 7, 8, 9, 10) )
typename std::common_type<T, Ts...>::type
metashell::expression_instantiated<true>
>
sum(T t_, Ts... ts_)
{
return t_ + sum(ts_...);
}

sum(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
Summarising numbers
sum.hpp
#include <type_traits>

template <class T>


$ metashell
T sum(T t_) { return t_; }
/* … */
> #include "sum.hpp"
> #include <metashell/instantiate_expression.hpp>
template <class T, class...
> METASHELL_INSTANTIATE_EXPRESSION( sum(1, 2, Ts>
3, 4, 5, 6, 7, 8, 9, 10) )
typename std::common_type<T, Ts...>::type
metashell::expression_instantiated<true>
> #msh mdb METASHELL_INSTANTIATE_EXPRESSION( sum(1, 2, 3, 4, 5, 6, 7, 8, 9, 10) )
sum(T t_, Ts... ts_)
{
return t_ + sum(ts_...);
}

sum(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
Summarising numbers
sum.hpp
#include <type_traits>

template <class T>


$ metashell
T sum(T t_) { return t_; }
/* … */
> #include "sum.hpp"
> #include <metashell/instantiate_expression.hpp>
template <class T, class...
> METASHELL_INSTANTIATE_EXPRESSION( sum(1, 2, Ts>
3, 4, 5, 6, 7, 8, 9, 10) )
typename std::common_type<T, Ts...>::type
metashell::expression_instantiated<true>
> #msh mdb METASHELL_INSTANTIATE_EXPRESSION( sum(1, 2, 3, 4, 5, 6, 7, 8, 9, 10) )
sum(T
For t_,"help".
help, type Ts... ts_)
{
Metaprogram started
(mdb)
return t_ + sum(ts_...);
}

sum(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
Summarising numbers
sum.hpp
#include <type_traits>

template <class T>


$ metashell
T sum(T t_) { return t_; }
/* … */
> #include "sum.hpp"
> #include <metashell/instantiate_expression.hpp>
template <class T, class...
> METASHELL_INSTANTIATE_EXPRESSION( sum(1, 2, Ts>
3, 4, 5, 6, 7, 8, 9, 10) )
typename std::common_type<T, Ts...>::type
metashell::expression_instantiated<true>
> #msh mdb METASHELL_INSTANTIATE_EXPRESSION( sum(1, 2, 3, 4, 5, 6, 7, 8, 9, 10) )
sum(T
For t_,"help".
help, type Ts... ts_)
{
Metaprogram started
(mdb) ft
return t_ + sum(ts_...);
}

sum(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
Summarising numbers
sum.hpp
#include <type_traits>

template <class T>


$ metashell
T sum(T t_) { return t_; }
/* … */
> #include "sum.hpp"
> #include <metashell/instantiate_expression.hpp>
template <class T, class...
> METASHELL_INSTANTIATE_EXPRESSION( sum(1, 2, Ts>
3, 4, 5, 6, 7, 8, 9, 10) )
typename std::common_type<T, Ts...>::type
metashell::expression_instantiated<true>
> #msh mdb METASHELL_INSTANTIATE_EXPRESSION( sum(1, 2, 3, 4, 5, 6, 7, 8, 9, 10) )
sum(T
For t_,"help".
help, type Ts... ts_)
{
Metaprogram started
(mdb) ft
return t_ + sum(ts_...);
METASHELL_INSTANTIATE_EXPRESSION( sum(1, 2, 3, 4, 5, 6, 7, 8, 9, 10) )
}
+ sum<int, int, int, int, int, int, int, int, int, int> (TemplateInstantiation from <stdin>:2:26)
| ` sum<int, int, int, int, int, int, int, int, int> (TemplateInstantiation from ./sum.hpp:12:15)
| ` sum<int, int, int, int, int, int, int, int> (TemplateInstantiation from ./sum.hpp:12:15)
| ` sum<int, int, int, int, int, int, int> (TemplateInstantiation from ./sum.hpp:12:15)
| ` sum<int, int, int, int, int, int> (TemplateInstantiation from ./sum.hpp:12:15)
| ` sum<int, int, int, int, int> (TemplateInstantiation from ./sum.hpp:12:15)
| ` sum<int, int, int, int> (TemplateInstantiation from ./sum.hpp:12:15)
| ` sum<int, int, int> (TemplateInstantiation from ./sum.hpp:12:15)
| ` sum<int, int> (TemplateInstantiation from ./sum.hpp:12:15)
| ` sum<int> (TemplateInstantiation from ./sum.hpp:12:15)
` metashell::expression_instantiated<true> (TemplateInstantiation from <stdin>:2:99)

sum(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
An STL example

 What gets instantiated when you create an


empty std::string?
An STL example

 What gets instantiated when you create an


empty std::string?
>
An STL example

 What gets instantiated when you create an


empty std::string?
> #include <metashell/instantiate_expression.hpp>
>
An STL example

 What gets instantiated when you create an


empty std::string?
> #include <metashell/instantiate_expression.hpp>
> #include <string>
>
An STL example

 What gets instantiated when you create an


empty std::string?
> #include <metashell/instantiate_expression.hpp>
> #include <string>
> #msh mdb METASHELL_INSTANTIATE_EXPRESSION( std::string() )
An STL example

 What gets instantiated when you create an


empty std::string?
> #include <metashell/instantiate_expression.hpp>
> #include <string>
> #msh mdb METASHELL_INSTANTIATE_EXPRESSION( std::string() )
For help, type "help".
Metaprogram started
(mdb)
An STL example

 What gets instantiated when you create an


empty std::string?
> #include <metashell/instantiate_expression.hpp>
> #include <string>
> #msh mdb METASHELL_INSTANTIATE_EXPRESSION( std::string() )
For help, type "help".
Metaprogram started
(mdb) ft
An STL example

 What gets instantiated when you create an


METASHELL_INSTANTIATE_EXPRESSION( std::string() )
+ std::basic_string<char, std::char_traits<char>, std::allocator<char> > (Memoization from <stdin>:2:26)
| + std::allocator<char> (Memoization from /usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/bits/basic_string.h:114:24)

empty std::string?
| | + std::__allocator_base (TemplateInstantiation from /usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/bits/allocator.h:92:29)
| | ` __gnu_cxx::new_allocator<char> (TemplateInstantiation from /usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/bits/allocator.h:92:29)
| + std::allocator<char>::rebind<char> (TemplateInstantiation from /usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/bits/basic_string.h:114:32)
| + std::char_traits<char> (Memoization from /usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/bits/basic_string.h:119:24)
| + std::allocator<char> (Memoization from /usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/bits/basic_string.h:121:24)
| + std::basic_string<char, std::char_traits<char>, std::allocator<char> >::_Alloc_hider (TemplateInstantiation from /usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/bit
| | s/basic_string.h:289:28)
> #include <metashell/instantiate_expression.hpp>
| | + std::allocator<char> (Memoization from /usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/bits/basic_string.h:272:29)
> #include <string>
| | ` std::allocator<char>::allocator<char> (TemplateInstantiation from /usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/bits/allocator.h:151:25)
| ` std::basic_string<char, std::char_traits<char>, std::allocator<char> >::_Alloc_hider (Memoization from /usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/bits/basic_st
| > #msh mdb METASHELL_INSTANTIATE_EXPRESSION( std::string() )
ring.h:289:28)
+ std::char_traits<char> (Memoization from <stdin>:2:26)
For help, type "help".
+ std::allocator<char> (Memoization from <stdin>:2:26)
+ metashell::expression_instantiated<true> (TemplateInstantiation from <stdin>:2:78)
Metaprogram started
` std::basic_string<char, std::char_traits<char>, std::allocator<char> >::basic_string (TemplateInstantiation from <stdin>:2:26)
+ std::basic_string<char, std::char_traits<char>, std::allocator<char> > (Memoization from /usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/bits/basic_string.h:508:26)
(mdb) ft
+ std::basic_string<char, std::char_traits<char>, std::allocator<char> >::_Alloc_hider (Memoization from /usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/bits/basic_st
| ring.h:508:9)
+ std::allocator<char> (Memoization from /usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/bits/basic_string.h:272:14)
+ std::basic_string<char, std::char_traits<char>, std::allocator<char> > (Memoization from /usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/bits/basic_string.h:511:7)
+ std::basic_string<char, std::char_traits<char>, std::allocator<char> >::_Rep (Memoization from /usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/bits/basic_string.h:5
| 11:30)
| + std::basic_string<char, std::char_traits<char>, std::allocator<char> > (Memoization from /usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/bits/basic_string.h:155:2
| | 1)
| + std::basic_string<char, std::char_traits<char>, std::allocator<char> >::_Rep_base (Memoization from /usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/bits/basic_str
| | ing.h:155:21)
| | ` std::basic_string<char, std::char_traits<char>, std::allocator<char> > (Memoization from /usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/bits/basic_string.h:150
| | :2)
| + std::allocator<char> (Memoization from /usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/bits/basic_string.h:158:19)
| + std::allocator<char>::rebind<char> (Memoization from /usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/bits/basic_string.h:158:27)
| ` std::basic_string<char, std::char_traits<char>, std::allocator<char> > (Memoization from /usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/bits/basic_string.h:173:1
| 5)
+ std::basic_string<char, std::char_traits<char>, std::allocator<char> >::_M_data (TemplateInstantiation from /usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/bits/bas
| ic_string.h:511:8)
| + std::basic_string<char, std::char_traits<char>, std::allocator<char> > (Memoization from /usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/bits/basic_string.h:293:1
| | 7)
| + std::basic_string<char, std::char_traits<char>, std::allocator<char> >::_Alloc_hider (Memoization from /usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/bits/basic_
| | string.h:293:28)
| + std::basic_string<char, std::char_traits<char>, std::allocator<char> > (Memoization from /usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/bits/basic_string.h:297:1
| | 7)
| ` std::basic_string<char, std::char_traits<char>, std::allocator<char> >::_Alloc_hider (Memoization from /usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/bits/basic_
| string.h:297:28)
+ std::basic_string<char, std::char_traits<char>, std::allocator<char> > (Memoization from /usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/bits/basic_string.h:439:21)
+ std::basic_string<char, std::char_traits<char>, std::allocator<char> >::_Rep (Memoization from /usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/bits/basic_string.h:4
| 39:35)
+ std::allocator<char> (Memoization from /usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/bits/basic_string.h:439:50)
+ std::basic_string<char, std::char_traits<char>, std::allocator<char> > (Memoization from /usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/bits/basic_string.h:439:9)
` std::basic_string<char, std::char_traits<char>, std::allocator<char> >::_Alloc_hider (Memoization from /usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/bits/basic_st
ring.h:439:9)
An STL example

 What gets instantiated when you create an


METASHELL_INSTANTIATE_EXPRESSION( std::string() )
+ std::basic_string<char, std::char_traits<char>, std::allocator<char> > (Memoization from <stdin>:2:26)
| + std::allocator<char> (Memoization from /usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/bits/basic_string.h:114:24)

empty std::string?
| | + std::__allocator_base (TemplateInstantiation from /usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/bits/allocator.h:92:29)
| | ` __gnu_cxx::new_allocator<char> (TemplateInstantiation from /usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/bits/allocator.h:92:29)
| + std::allocator<char>::rebind<char> (TemplateInstantiation from /usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/bits/basic_string.h:114:32)
| + std::char_traits<char> (Memoization from /usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/bits/basic_string.h:119:24)
| + std::allocator<char> (Memoization from /usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/bits/basic_string.h:121:24)
| + std::basic_string<char, std::char_traits<char>, std::allocator<char> >::_Alloc_hider (TemplateInstantiation from /usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/bit
| | s/basic_string.h:289:28)
> #include <metashell/instantiate_expression.hpp>
| | + std::allocator<char> (Memoization from /usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/bits/basic_string.h:272:29)
> #include <string>
| | ` std::allocator<char>::allocator<char> (TemplateInstantiation from /usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/bits/allocator.h:151:25)
| ` std::basic_string<char, std::char_traits<char>, std::allocator<char> >::_Alloc_hider (Memoization from /usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/bits/basic_st
| > #msh mdb METASHELL_INSTANTIATE_EXPRESSION( std::string() )
ring.h:289:28)
+ std::char_traits<char> (Memoization from <stdin>:2:26)
For help, type "help".
+ std::allocator<char> (Memoization from <stdin>:2:26)
+ metashell::expression_instantiated<true> (TemplateInstantiation from <stdin>:2:78)
Metaprogram started
` std::basic_string<char, std::char_traits<char>, std::allocator<char> >::basic_string (TemplateInstantiation from <stdin>:2:26)
+ std::basic_string<char, std::char_traits<char>, std::allocator<char> > (Memoization from /usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/bits/basic_string.h:508:26)
(mdb) ft
+ std::basic_string<char, std::char_traits<char>, std::allocator<char> >::_Alloc_hider (Memoization from /usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/bits/basic_st
| ring.h:508:9)
+ std::allocator<char> (Memoization from /usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/bits/basic_string.h:272:14)
+ std::basic_string<char, std::char_traits<char>, std::allocator<char> > (Memoization from /usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/bits/basic_string.h:511:7)
+ std::basic_string<char, std::char_traits<char>, std::allocator<char> >::_Rep (Memoization from /usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/bits/basic_string.h:5
| 11:30)
| + std::basic_string<char, std::char_traits<char>, std::allocator<char> > (Memoization from /usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/bits/basic_string.h:155:2
| | 1)
| + std::basic_string<char, std::char_traits<char>, std::allocator<char> >::_Rep_base (Memoization from /usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/bits/basic_str
| | ing.h:155:21)
| | ` std::basic_string<char, std::char_traits<char>, std::allocator<char> > (Memoization from /usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/bits/basic_string.h:150
| | :2)
| + std::allocator<char> (Memoization from /usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/bits/basic_string.h:158:19)
| + std::allocator<char>::rebind<char> (Memoization from /usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/bits/basic_string.h:158:27)
| ` std::basic_string<char, std::char_traits<char>, std::allocator<char> > (Memoization from /usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/bits/basic_string.h:173:1
| 5)
+ std::basic_string<char, std::char_traits<char>, std::allocator<char> >::_M_data (TemplateInstantiation from /usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/bits/bas
| ic_string.h:511:8)
| + std::basic_string<char, std::char_traits<char>, std::allocator<char> > (Memoization from /usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/bits/basic_string.h:293:1
| | 7)
| + std::basic_string<char, std::char_traits<char>, std::allocator<char> >::_Alloc_hider (Memoization from /usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/bits/basic_
| | string.h:293:28)
| + std::basic_string<char, std::char_traits<char>, std::allocator<char> > (Memoization from /usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/bits/basic_string.h:297:1
| | 7)
| ` std::basic_string<char, std::char_traits<char>, std::allocator<char> >::_Alloc_hider (Memoization from /usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/bits/basic_
| string.h:297:28)
+ std::basic_string<char, std::char_traits<char>, std::allocator<char> > (Memoization from /usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/bits/basic_string.h:439:21)
+ std::basic_string<char, std::char_traits<char>, std::allocator<char> >::_Rep (Memoization from /usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/bits/basic_string.h:4
| 39:35)
+ std::allocator<char> (Memoization from /usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/bits/basic_string.h:439:50)
+ std::basic_string<char, std::char_traits<char>, std::allocator<char> > (Memoization from /usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/bits/basic_string.h:439:9)
` std::basic_string<char, std::char_traits<char>, std::allocator<char> >::_Alloc_hider (Memoization from /usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/bits/basic_st
ring.h:439:9)
Compilation speed

 Heavy template usage can lead to long


compilation times
 To optimise it, we need to understand where
this comes from
Example code

 Boost.Graph example: astar-cities.cpp

$ time clang++ astar-cities.cpp

real 0m3.726s
user 0m3.297s
sys 0m0.139s
Templight + Callgrind

 KcacheGrind
 Instantiation tree
 Profiling
Templight + Callgrind
”What gets instantiated?”
”What gets instantiated?”
$ templight-convert -f text -i astar-cities.o.trace.pbf \
| grep 'Name =' | sed 's/^ Name = //' | sort --unique
”What gets instantiated?”
$ templight-convert -f text -i astar-cities.o.trace.pbf \
| grep 'Name =' | sed 's/^ Name = //' | sort --unique

. . .

boost::detail::deduce_source_char_impl<boost::detail::deduce_character_type_later<unsigned long> >


boost::detail::deduce_source_char_impl<deduce_character_type_later<type-parameter-0-0> >
boost::detail::deduce_source_char<unsigned long>
boost::detail::deduce_target_char_impl<char>
boost::detail::deduce_target_char<std::basic_string<char> >
boost::detail::dereference_iterator
boost::detail::digit_traits<int>
boost::detail::digit_traits<long>
boost::detail::digit_traits_select<true>
boost::detail::digit_traits_select<true>::traits<int>
boost::detail::digit_traits_select<true>::traits<long>
boost::detail::do_not_construct_out_stream_t
boost::detail::dummy_constructor
boost::detail::dummy_no_property_iterator
boost::detail::dummy_pmap_reference
boost::detail::dummy_property_copier
boost::detail::edge_base<boost::undirected_tag, unsigned long>
boost::detail::edge_base<boost::undirected_tag, unsigned long>::edge_base
boost::detail::edge_desc_impl<boost::undirected_tag, unsigned long>
boost::detail::edge_desc_impl<boost::undirected_tag, unsigned long>::edge_desc_impl
boost::detail::edge_desc_impl<boost::undirected_tag, unsigned long>::get_property

. . .
When things go wrong

 So far we have assumed, that the code


compiles
 When the code fails to compile, we need to
debug the compilation process
Example code

class person
{
// ...
};
Example code

class person
{
// ...
};

int main()
{
std::vector<person> people;

}
Example code

class person
{
// ...
};

int main()
{
std::vector<person> people;

std::sort(people.begin(), people.end());
}
Example code
In file included from person.cpp:2: /usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/bits/stl_algo.h:85:16: error: invalid operands to binary expression ('person' and 'person')
In file included from /usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/algorithm:62: if (*__a < *__b)
/usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/bits/stl_algo.h:1935:11: error: invalid operands to binary expression ('person' and 'person') ~~~~ ^ ~~~~
if (*__i < *__first) /usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/bits/stl_algo.h:2282:12: note: in instantiation of function template specialization 'std::__move_median_to_first<__gnu_cxx::__normal_iterator<person *, std::vector<person, std::allocator<person> > > >' requested here
~~~~ ^ ~~~~~~~~ std::__move_median_to_first(__first, __first + 1, __mid, __last - 1);
/usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/bits/stl_algo.h:5299:12: note: in instantiation of function template specialization 'std::__heap_select<__gnu_cxx::__normal_iterator<person *, std::vector<person, std::allocator<person> > > >' requested here ^
std::__heap_select(__first, __middle, __last); /usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/bits/stl_algo.h:2315:11: note: in instantiation of function template specialization 'std::__unguarded_partition_pivot<__gnu_cxx::__normal_iterator<person *, std::vector<person, std::allocator<person> > > >' requested here
^ std::__unguarded_partition_pivot(__first, __last);
/usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/bits/stl_algo.h:2310:24: note: in instantiation of function template specialization 'std::partial_sort<__gnu_cxx::__normal_iterator<person *, std::vector<person, std::allocator<person> > > >' requested here ^
_GLIBCXX_STD_A::partial_sort(__first, __last, __last); /usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/bits/stl_algo.h:5451:9: note: in instantiation of function template specialization 'std::__introsort_loop<__gnu_cxx::__normal_iterator<person *, std::vector<person, std::allocator<person> > >, long>' requested here
^ std::__introsort_loop(__first, __last,
/usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/bits/stl_algo.h:5451:9: note: in instantiation of function template specialization 'std::__introsort_loop<__gnu_cxx::__normal_iterator<person *, std::vector<person, std::allocator<person> > >, long>' requested here ^
std::__introsort_loop(__first, __last, person.cpp:12:8: note: in instantiation of function template specialization 'std::sort<__gnu_cxx::__normal_iterator<person *, std::vector<person, std::allocator<person> > > >' requested here
^ std::sort(people.begin(), people.end());
person.cpp:12:8: note: in instantiation of function template specialization 'std::sort<__gnu_cxx::__normal_iterator<person *, std::vector<person, std::allocator<person> > > >' requested here ^
std::sort(people.begin(), people.end()); /usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/bits/stl_pair.h:220:5: note: candidate template ignored: could not match 'pair<type-parameter-0-0, type-parameter-0-1>' against 'person'
^ operator<(const pair<_T1, _T2>& __x, const pair<_T1, _T2>& __y)
/usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/bits/stl_pair.h:220:5: note: candidate template ignored: could not match 'pair<type-parameter-0-0, type-parameter-0-1>' against 'person' ^
operator<(const pair<_T1, _T2>& __x, const pair<_T1, _T2>& __y) /usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/bits/stl_iterator.h:297:5: note: candidate template ignored: could not match 'reverse_iterator<type-parameter-0-0>' against 'person'
^ operator<(const reverse_iterator<_Iterator>& __x,
/usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/bits/stl_iterator.h:297:5: note: candidate template ignored: could not match 'reverse_iterator<type-parameter-0-0>' against 'person' ^
operator<(const reverse_iterator<_Iterator>& __x, /usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/bits/stl_iterator.h:347:5: note: candidate template ignored: could not match 'reverse_iterator<type-parameter-0-0>' against 'person'
^ operator<(const reverse_iterator<_IteratorL>& __x,
/usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/bits/stl_iterator.h:347:5: note: candidate template ignored: could not match 'reverse_iterator<type-parameter-0-0>' against 'person' ^
operator<(const reverse_iterator<_IteratorL>& __x, /usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/bits/stl_vector.h:1421:5: note: candidate template ignored: could not match 'vector<type-parameter-0-0, type-parameter-0-1>' against 'person'
^ operator<(const vector<_Tp, _Alloc>& __x, const vector<_Tp, _Alloc>& __y)
/usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/bits/stl_vector.h:1421:5: note: candidate template ignored: could not match 'vector<type-parameter-0-0, type-parameter-0-1>' against 'person' ^
operator<(const vector<_Tp, _Alloc>& __x, const vector<_Tp, _Alloc>& __y) In file included from person.cpp:2:
^ In file included from /usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/algorithm:62:
In file included from person.cpp:2: /usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/bits/stl_algo.h:2242:20: error: invalid operands to binary expression ('person' and 'const person')
In file included from /usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/algorithm:62: while (*__first < __pivot)
In file included from /usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/bits/stl_algo.h:61: ~~~~~~~~ ^ ~~~~~~~
/usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/bits/stl_heap.h:235:35: error: invalid operands to binary expression ('person' and 'person') /usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/bits/stl_algo.h:2283:19: note: in instantiation of function template specialization 'std::__unguarded_partition<__gnu_cxx::__normal_iterator<person *, std::vector<person, std::allocator<person> > >, person>' requested here
if (*(__first + __secondChild) < *(__first + (__secondChild - 1))) return std::__unguarded_partition(__first + 1, __last, *__first);
~~~~~~~~~~~~~~~~~~~~~~~~~~ ^ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ^
/usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/bits/stl_heap.h:407:9: note: in instantiation of function template specialization 'std::__adjust_heap<__gnu_cxx::__normal_iterator<person *, std::vector<person, std::allocator<person> > >, long, person>' requested here /usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/bits/stl_algo.h:2315:11: note: in instantiation of function template specialization 'std::__unguarded_partition_pivot<__gnu_cxx::__normal_iterator<person *, std::vector<person, std::allocator<person> > > >' requested here
std::__adjust_heap(__first, __parent, __len, _GLIBCXX_MOVE(__value)); std::__unguarded_partition_pivot(__first, __last);
^ ^
/usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/bits/stl_algo.h:1933:12: note: in instantiation of function template specialization 'std::make_heap<__gnu_cxx::__normal_iterator<person *, std::vector<person, std::allocator<person> > > >' requested here /usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/bits/stl_algo.h:5451:9: note: in instantiation of function template specialization 'std::__introsort_loop<__gnu_cxx::__normal_iterator<person *, std::vector<person, std::allocator<person> > >, long>' requested here
std::make_heap(__first, __middle); std::__introsort_loop(__first, __last,
^ ^
/usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/bits/stl_algo.h:5299:12: note: in instantiation of function template specialization 'std::__heap_select<__gnu_cxx::__normal_iterator<person *, std::vector<person, std::allocator<person> > > >' requested here person.cpp:12:8: note: in instantiation of function template specialization 'std::sort<__gnu_cxx::__normal_iterator<person *, std::vector<person, std::allocator<person> > > >' requested here
std::__heap_select(__first, __middle, __last); std::sort(people.begin(), people.end());
^ ^
/usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/bits/stl_algo.h:2310:24: note: in instantiation of function template specialization 'std::partial_sort<__gnu_cxx::__normal_iterator<person *, std::vector<person, std::allocator<person> > > >' requested here /usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/bits/stl_pair.h:220:5: note: candidate template ignored: could not match 'pair<type-parameter-0-0, type-parameter-0-1>' against 'person'
_GLIBCXX_STD_A::partial_sort(__first, __last, __last); operator<(const pair<_T1, _T2>& __x, const pair<_T1, _T2>& __y)
^ ^
/usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/bits/stl_algo.h:5451:9: note: in instantiation of function template specialization 'std::__introsort_loop<__gnu_cxx::__normal_iterator<person *, std::vector<person, std::allocator<person> > >, long>' requested here /usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/bits/stl_iterator.h:297:5: note: candidate template ignored: could not match 'reverse_iterator<type-parameter-0-0>' against 'person'
std::__introsort_loop(__first, __last, operator<(const reverse_iterator<_Iterator>& __x,
^ ^
person.cpp:12:8: note: in instantiation of function template specialization 'std::sort<__gnu_cxx::__normal_iterator<person *, std::vector<person, std::allocator<person> > > >' requested here /usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/bits/stl_iterator.h:347:5: note: candidate template ignored: could not match 'reverse_iterator<type-parameter-0-0>' against 'person'
std::sort(people.begin(), people.end()); operator<(const reverse_iterator<_IteratorL>& __x,
^ ^
/usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/bits/stl_pair.h:220:5: note: candidate template ignored: could not match 'pair<type-parameter-0-0, type-parameter-0-1>' against 'person' /usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/bits/stl_vector.h:1421:5: note: candidate template ignored: could not match 'vector<type-parameter-0-0, type-parameter-0-1>' against 'person'
operator<(const pair<_T1, _T2>& __x, const pair<_T1, _T2>& __y) operator<(const vector<_Tp, _Alloc>& __x, const vector<_Tp, _Alloc>& __y)
^ ^
/usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/bits/stl_iterator.h:297:5: note: candidate template ignored: could not match 'reverse_iterator<type-parameter-0-0>' against 'person' In file included from person.cpp:2:
operator<(const reverse_iterator<_Iterator>& __x, In file included from /usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/algorithm:62:
^ /usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/bits/stl_algo.h:2245:19: error: invalid operands to binary expression ('const person' and 'person')
/usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/bits/stl_iterator.h:347:5: note: candidate template ignored: could not match 'reverse_iterator<type-parameter-0-0>' against 'person' while (__pivot < *__last)
operator<(const reverse_iterator<_IteratorL>& __x, ~~~~~~~ ^ ~~~~~~~
^ /usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/bits/stl_pair.h:220:5: note: candidate template ignored: could not match 'pair<type-parameter-0-0, type-parameter-0-1>' against 'const person'
/usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/bits/stl_vector.h:1421:5: note: candidate template ignored: could not match 'vector<type-parameter-0-0, type-parameter-0-1>' against 'person' operator<(const pair<_T1, _T2>& __x, const pair<_T1, _T2>& __y)
operator<(const vector<_Tp, _Alloc>& __x, const vector<_Tp, _Alloc>& __y) ^
^ /usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/bits/stl_iterator.h:297:5: note: candidate template ignored: could not match 'reverse_iterator<type-parameter-0-0>' against 'const person'
In file included from person.cpp:2: operator<(const reverse_iterator<_Iterator>& __x,
In file included from /usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/algorithm:62: ^
In file included from /usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/bits/stl_algo.h:61: /usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/bits/stl_iterator.h:347:5: note: candidate template ignored: could not match 'reverse_iterator<type-parameter-0-0>' against 'const person'
/usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/bits/stl_heap.h:135:64: error: invalid operands to binary expression ('person' and 'person') operator<(const reverse_iterator<_IteratorL>& __x,
while (__holeIndex > __topIndex && *(__first + __parent) < __value) ^
~~~~~~~~~~~~~~~~~~~~~ ^ ~~~~~~~ /usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/bits/stl_vector.h:1421:5: note: candidate template ignored: could not match 'vector<type-parameter-0-0, type-parameter-0-1>' against 'const person'
/usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/bits/stl_heap.h:247:12: note: in instantiation of function template specialization 'std::__push_heap<__gnu_cxx::__normal_iterator<person *, std::vector<person, std::allocator<person> > >, long, person>' requested here operator<(const vector<_Tp, _Alloc>& __x, const vector<_Tp, _Alloc>& __y)
std::__push_heap(__first, __holeIndex, __topIndex, ^
^ In file included from person.cpp:2:
/usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/bits/stl_heap.h:407:9: note: in instantiation of function template specialization 'std::__adjust_heap<__gnu_cxx::__normal_iterator<person *, std::vector<person, std::allocator<person> > >, long, person>' requested here In file included from /usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/algorithm:62:
std::__adjust_heap(__first, __parent, __len, _GLIBCXX_MOVE(__value)); /usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/bits/stl_algo.h:2137:13: error: invalid operands to binary expression ('person' and 'person')
^ if (*__i < *__first)
/usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/bits/stl_algo.h:1933:12: note: in instantiation of function template specialization 'std::make_heap<__gnu_cxx::__normal_iterator<person *, std::vector<person, std::allocator<person> > > >' requested here ~~~~ ^ ~~~~~~~~
std::make_heap(__first, __middle); /usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/bits/stl_algo.h:2211:9: note: in instantiation of function template specialization 'std::__insertion_sort<__gnu_cxx::__normal_iterator<person *, std::vector<person, std::allocator<person> > > >' requested here
^ std::__insertion_sort(__first, __first + int(_S_threshold));
/usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/bits/stl_algo.h:5299:12: note: in instantiation of function template specialization 'std::__heap_select<__gnu_cxx::__normal_iterator<person *, std::vector<person, std::allocator<person> > > >' requested here ^
std::__heap_select(__first, __middle, __last); /usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/bits/stl_algo.h:5453:9: note: in instantiation of function template specialization 'std::__final_insertion_sort<__gnu_cxx::__normal_iterator<person *, std::vector<person, std::allocator<person> > > >' requested here
^ std::__final_insertion_sort(__first, __last);

class person
/usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/bits/stl_algo.h:2310:24: note: in instantiation of function template specialization 'std::partial_sort<__gnu_cxx::__normal_iterator<person *, std::vector<person, std::allocator<person> > > >' requested here ^
_GLIBCXX_STD_A::partial_sort(__first, __last, __last); person.cpp:12:8: note: in instantiation of function template specialization 'std::sort<__gnu_cxx::__normal_iterator<person *, std::vector<person, std::allocator<person> > > >' requested here
^ std::sort(people.begin(), people.end());
/usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/bits/stl_algo.h:5451:9: note: in instantiation of function template specialization 'std::__introsort_loop<__gnu_cxx::__normal_iterator<person *, std::vector<person, std::allocator<person> > >, long>' requested here ^
std::__introsort_loop(__first, __last,

{
// ...
};

int main()
{
std::vector<person> people;

std::sort(people.begin(), people.end());
}
Example code
In file included from person.cpp:2: /usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/bits/stl_algo.h:85:16: error: invalid operands to binary expression ('person' and 'person')
In file included from /usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/algorithm:62: if (*__a < *__b)
/usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/bits/stl_algo.h:1935:11: error: invalid operands to binary expression ('person' and 'person') ~~~~ ^ ~~~~
if (*__i < *__first) /usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/bits/stl_algo.h:2282:12: note: in instantiation of function template specialization 'std::__move_median_to_first<__gnu_cxx::__normal_iterator<person *, std::vector<person, std::allocator<person> > > >' requested here
~~~~ ^ ~~~~~~~~ std::__move_median_to_first(__first, __first + 1, __mid, __last - 1);
/usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/bits/stl_algo.h:5299:12: note: in instantiation of function template specialization 'std::__heap_select<__gnu_cxx::__normal_iterator<person *, std::vector<person, std::allocator<person> > > >' requested here ^
std::__heap_select(__first, __middle, __last); /usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/bits/stl_algo.h:2315:11: note: in instantiation of function template specialization 'std::__unguarded_partition_pivot<__gnu_cxx::__normal_iterator<person *, std::vector<person, std::allocator<person> > > >' requested here
^ std::__unguarded_partition_pivot(__first, __last);
/usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/bits/stl_algo.h:2310:24: note: in instantiation of function template specialization 'std::partial_sort<__gnu_cxx::__normal_iterator<person *, std::vector<person, std::allocator<person> > > >' requested here ^
_GLIBCXX_STD_A::partial_sort(__first, __last, __last); /usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/bits/stl_algo.h:5451:9: note: in instantiation of function template specialization 'std::__introsort_loop<__gnu_cxx::__normal_iterator<person *, std::vector<person, std::allocator<person> > >, long>' requested here
^ std::__introsort_loop(__first, __last,
/usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/bits/stl_algo.h:5451:9: note: in instantiation of function template specialization 'std::__introsort_loop<__gnu_cxx::__normal_iterator<person *, std::vector<person, std::allocator<person> > >, long>' requested here ^
std::__introsort_loop(__first, __last, person.cpp:12:8: note: in instantiation of function template specialization 'std::sort<__gnu_cxx::__normal_iterator<person *, std::vector<person, std::allocator<person> > > >' requested here
^ std::sort(people.begin(), people.end());
person.cpp:12:8: note: in instantiation of function template specialization 'std::sort<__gnu_cxx::__normal_iterator<person *, std::vector<person, std::allocator<person> > > >' requested here ^
std::sort(people.begin(), people.end()); /usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/bits/stl_pair.h:220:5: note: candidate template ignored: could not match 'pair<type-parameter-0-0, type-parameter-0-1>' against 'person'
^ operator<(const pair<_T1, _T2>& __x, const pair<_T1, _T2>& __y)
/usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/bits/stl_pair.h:220:5: note: candidate template ignored: could not match 'pair<type-parameter-0-0, type-parameter-0-1>' against 'person' ^
operator<(const pair<_T1, _T2>& __x, const pair<_T1, _T2>& __y) /usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/bits/stl_iterator.h:297:5: note: candidate template ignored: could not match 'reverse_iterator<type-parameter-0-0>' against 'person'
^ operator<(const reverse_iterator<_Iterator>& __x,
/usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/bits/stl_iterator.h:297:5: note: candidate template ignored: could not match 'reverse_iterator<type-parameter-0-0>' against 'person' ^
operator<(const reverse_iterator<_Iterator>& __x, /usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/bits/stl_iterator.h:347:5: note: candidate template ignored: could not match 'reverse_iterator<type-parameter-0-0>' against 'person'
^ operator<(const reverse_iterator<_IteratorL>& __x,
/usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/bits/stl_iterator.h:347:5: note: candidate template ignored: could not match 'reverse_iterator<type-parameter-0-0>' against 'person' ^
operator<(const reverse_iterator<_IteratorL>& __x, /usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/bits/stl_vector.h:1421:5: note: candidate template ignored: could not match 'vector<type-parameter-0-0, type-parameter-0-1>' against 'person'
^ operator<(const vector<_Tp, _Alloc>& __x, const vector<_Tp, _Alloc>& __y)
/usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/bits/stl_vector.h:1421:5: note: candidate template ignored: could not match 'vector<type-parameter-0-0, type-parameter-0-1>' against 'person' ^
operator<(const vector<_Tp, _Alloc>& __x, const vector<_Tp, _Alloc>& __y) In file included from person.cpp:2:
^ In file included from /usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/algorithm:62:
In file included from person.cpp:2: /usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/bits/stl_algo.h:2242:20: error: invalid operands to binary expression ('person' and 'const person')
In file included from /usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/algorithm:62: while (*__first < __pivot)
In file included from /usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/bits/stl_algo.h:61: ~~~~~~~~ ^ ~~~~~~~
/usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/bits/stl_heap.h:235:35: error: invalid operands to binary expression ('person' and 'person') /usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/bits/stl_algo.h:2283:19: note: in instantiation of function template specialization 'std::__unguarded_partition<__gnu_cxx::__normal_iterator<person *, std::vector<person, std::allocator<person> > >, person>' requested here
if (*(__first + __secondChild) < *(__first + (__secondChild - 1))) return std::__unguarded_partition(__first + 1, __last, *__first);
~~~~~~~~~~~~~~~~~~~~~~~~~~ ^ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ^
/usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/bits/stl_heap.h:407:9: note: in instantiation of function template specialization 'std::__adjust_heap<__gnu_cxx::__normal_iterator<person *, std::vector<person, std::allocator<person> > >, long, person>' requested here /usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/bits/stl_algo.h:2315:11: note: in instantiation of function template specialization 'std::__unguarded_partition_pivot<__gnu_cxx::__normal_iterator<person *, std::vector<person, std::allocator<person> > > >' requested here
std::__adjust_heap(__first, __parent, __len, _GLIBCXX_MOVE(__value)); std::__unguarded_partition_pivot(__first, __last);
^ ^
/usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/bits/stl_algo.h:1933:12: note: in instantiation of function template specialization 'std::make_heap<__gnu_cxx::__normal_iterator<person *, std::vector<person, std::allocator<person> > > >' requested here /usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/bits/stl_algo.h:5451:9: note: in instantiation of function template specialization 'std::__introsort_loop<__gnu_cxx::__normal_iterator<person *, std::vector<person, std::allocator<person> > >, long>' requested here
std::make_heap(__first, __middle); std::__introsort_loop(__first, __last,
^ ^
/usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/bits/stl_algo.h:5299:12: note: in instantiation of function template specialization 'std::__heap_select<__gnu_cxx::__normal_iterator<person *, std::vector<person, std::allocator<person> > > >' requested here person.cpp:12:8: note: in instantiation of function template specialization 'std::sort<__gnu_cxx::__normal_iterator<person *, std::vector<person, std::allocator<person> > > >' requested here
std::__heap_select(__first, __middle, __last); std::sort(people.begin(), people.end());
^ ^
/usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/bits/stl_algo.h:2310:24: note: in instantiation of function template specialization 'std::partial_sort<__gnu_cxx::__normal_iterator<person *, std::vector<person, std::allocator<person> > > >' requested here /usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/bits/stl_pair.h:220:5: note: candidate template ignored: could not match 'pair<type-parameter-0-0, type-parameter-0-1>' against 'person'
_GLIBCXX_STD_A::partial_sort(__first, __last, __last); operator<(const pair<_T1, _T2>& __x, const pair<_T1, _T2>& __y)
^ ^
/usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/bits/stl_algo.h:5451:9: note: in instantiation of function template specialization 'std::__introsort_loop<__gnu_cxx::__normal_iterator<person *, std::vector<person, std::allocator<person> > >, long>' requested here /usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/bits/stl_iterator.h:297:5: note: candidate template ignored: could not match 'reverse_iterator<type-parameter-0-0>' against 'person'
std::__introsort_loop(__first, __last, operator<(const reverse_iterator<_Iterator>& __x,
^ ^
person.cpp:12:8: note: in instantiation of function template specialization 'std::sort<__gnu_cxx::__normal_iterator<person *, std::vector<person, std::allocator<person> > > >' requested here /usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/bits/stl_iterator.h:347:5: note: candidate template ignored: could not match 'reverse_iterator<type-parameter-0-0>' against 'person'
std::sort(people.begin(), people.end()); operator<(const reverse_iterator<_IteratorL>& __x,
^ ^
/usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/bits/stl_pair.h:220:5: note: candidate template ignored: could not match 'pair<type-parameter-0-0, type-parameter-0-1>' against 'person' /usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/bits/stl_vector.h:1421:5: note: candidate template ignored: could not match 'vector<type-parameter-0-0, type-parameter-0-1>' against 'person'
operator<(const pair<_T1, _T2>& __x, const pair<_T1, _T2>& __y) operator<(const vector<_Tp, _Alloc>& __x, const vector<_Tp, _Alloc>& __y)
^ ^
/usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/bits/stl_iterator.h:297:5: note: candidate template ignored: could not match 'reverse_iterator<type-parameter-0-0>' against 'person' In file included from person.cpp:2:
operator<(const reverse_iterator<_Iterator>& __x, In file included from /usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/algorithm:62:
^ /usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/bits/stl_algo.h:2245:19: error: invalid operands to binary expression ('const person' and 'person')
/usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/bits/stl_iterator.h:347:5: note: candidate template ignored: could not match 'reverse_iterator<type-parameter-0-0>' against 'person' while (__pivot < *__last)
operator<(const reverse_iterator<_IteratorL>& __x, ~~~~~~~ ^ ~~~~~~~
^ /usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/bits/stl_pair.h:220:5: note: candidate template ignored: could not match 'pair<type-parameter-0-0, type-parameter-0-1>' against 'const person'
/usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/bits/stl_vector.h:1421:5: note: candidate template ignored: could not match 'vector<type-parameter-0-0, type-parameter-0-1>' against 'person' operator<(const pair<_T1, _T2>& __x, const pair<_T1, _T2>& __y)
operator<(const vector<_Tp, _Alloc>& __x, const vector<_Tp, _Alloc>& __y) ^
^ /usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/bits/stl_iterator.h:297:5: note: candidate template ignored: could not match 'reverse_iterator<type-parameter-0-0>' against 'const person'
In file included from person.cpp:2: operator<(const reverse_iterator<_Iterator>& __x,
In file included from /usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/algorithm:62: ^
In file included from /usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/bits/stl_algo.h:61: /usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/bits/stl_iterator.h:347:5: note: candidate template ignored: could not match 'reverse_iterator<type-parameter-0-0>' against 'const person'
/usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/bits/stl_heap.h:135:64: error: invalid operands to binary expression ('person' and 'person') operator<(const reverse_iterator<_IteratorL>& __x,
while (__holeIndex > __topIndex && *(__first + __parent) < __value) ^
~~~~~~~~~~~~~~~~~~~~~ ^ ~~~~~~~ /usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/bits/stl_vector.h:1421:5: note: candidate template ignored: could not match 'vector<type-parameter-0-0, type-parameter-0-1>' against 'const person'
/usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/bits/stl_heap.h:247:12: note: in instantiation of function template specialization 'std::__push_heap<__gnu_cxx::__normal_iterator<person *, std::vector<person, std::allocator<person> > >, long, person>' requested here operator<(const vector<_Tp, _Alloc>& __x, const vector<_Tp, _Alloc>& __y)
std::__push_heap(__first, __holeIndex, __topIndex, ^
^ In file included from person.cpp:2:
/usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/bits/stl_heap.h:407:9: note: in instantiation of function template specialization 'std::__adjust_heap<__gnu_cxx::__normal_iterator<person *, std::vector<person, std::allocator<person> > >, long, person>' requested here In file included from /usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/algorithm:62:
std::__adjust_heap(__first, __parent, __len, _GLIBCXX_MOVE(__value)); /usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/bits/stl_algo.h:2137:13: error: invalid operands to binary expression ('person' and 'person')
^ if (*__i < *__first)
/usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/bits/stl_algo.h:1933:12: note: in instantiation of function template specialization 'std::make_heap<__gnu_cxx::__normal_iterator<person *, std::vector<person, std::allocator<person> > > >' requested here ~~~~ ^ ~~~~~~~~
std::make_heap(__first, __middle); /usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/bits/stl_algo.h:2211:9: note: in instantiation of function template specialization 'std::__insertion_sort<__gnu_cxx::__normal_iterator<person *, std::vector<person, std::allocator<person> > > >' requested here
^ std::__insertion_sort(__first, __first + int(_S_threshold));
/usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/bits/stl_algo.h:5299:12: note: in instantiation of function template specialization 'std::__heap_select<__gnu_cxx::__normal_iterator<person *, std::vector<person, std::allocator<person> > > >' requested here ^
std::__heap_select(__first, __middle, __last); /usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/bits/stl_algo.h:5453:9: note: in instantiation of function template specialization 'std::__final_insertion_sort<__gnu_cxx::__normal_iterator<person *, std::vector<person, std::allocator<person> > > >' requested here
^ std::__final_insertion_sort(__first, __last);

class person
/usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/bits/stl_algo.h:2310:24: note: in instantiation of function template specialization 'std::partial_sort<__gnu_cxx::__normal_iterator<person *, std::vector<person, std::allocator<person> > > >' requested here ^
_GLIBCXX_STD_A::partial_sort(__first, __last, __last); person.cpp:12:8: note: in instantiation of function template specialization 'std::sort<__gnu_cxx::__normal_iterator<person *, std::vector<person, std::allocator<person> > > >' requested here
^ std::sort(people.begin(), people.end());
/usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/bits/stl_algo.h:5451:9: note: in instantiation of function template specialization 'std::__introsort_loop<__gnu_cxx::__normal_iterator<person *, std::vector<person, std::allocator<person> > >, long>' requested here ^
std::__introsort_loop(__first, __last,

{
// ...
};

int main()
/usr/include/c++/4.8/bits/stl_algo.h:1935:11: error:
{
invalid operands to binary expression ('person' and 'person')
std::vector<person> people;
if (*__i < *__first)
~~~~ ^ ~~~~~~~~
std::sort(people.begin(), people.end());
}
Example code
In file included from person.cpp:2: /usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/bits/stl_algo.h:85:16: error: invalid operands to binary expression ('person' and 'person')
In file included from /usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/algorithm:62: if (*__a < *__b)
/usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/bits/stl_algo.h:1935:11: error: invalid operands to binary expression ('person' and 'person') ~~~~ ^ ~~~~
if (*__i < *__first) /usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/bits/stl_algo.h:2282:12: note: in instantiation of function template specialization 'std::__move_median_to_first<__gnu_cxx::__normal_iterator<person *, std::vector<person, std::allocator<person> > > >' requested here
~~~~ ^ ~~~~~~~~ std::__move_median_to_first(__first, __first + 1, __mid, __last - 1);
/usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/bits/stl_algo.h:5299:12: note: in instantiation of function template specialization 'std::__heap_select<__gnu_cxx::__normal_iterator<person *, std::vector<person, std::allocator<person> > > >' requested here ^
std::__heap_select(__first, __middle, __last); /usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/bits/stl_algo.h:2315:11: note: in instantiation of function template specialization 'std::__unguarded_partition_pivot<__gnu_cxx::__normal_iterator<person *, std::vector<person, std::allocator<person> > > >' requested here
^ std::__unguarded_partition_pivot(__first, __last);
/usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/bits/stl_algo.h:2310:24: note: in instantiation of function template specialization 'std::partial_sort<__gnu_cxx::__normal_iterator<person *, std::vector<person, std::allocator<person> > > >' requested here ^
_GLIBCXX_STD_A::partial_sort(__first, __last, __last); /usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/bits/stl_algo.h:5451:9: note: in instantiation of function template specialization 'std::__introsort_loop<__gnu_cxx::__normal_iterator<person *, std::vector<person, std::allocator<person> > >, long>' requested here
^ std::__introsort_loop(__first, __last,
/usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/bits/stl_algo.h:5451:9: note: in instantiation of function template specialization 'std::__introsort_loop<__gnu_cxx::__normal_iterator<person *, std::vector<person, std::allocator<person> > >, long>' requested here ^
std::__introsort_loop(__first, __last, person.cpp:12:8: note: in instantiation of function template specialization 'std::sort<__gnu_cxx::__normal_iterator<person *, std::vector<person, std::allocator<person> > > >' requested here
^ std::sort(people.begin(), people.end());
person.cpp:12:8: note: in instantiation of function template specialization 'std::sort<__gnu_cxx::__normal_iterator<person *, std::vector<person, std::allocator<person> > > >' requested here ^
std::sort(people.begin(), people.end()); /usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/bits/stl_pair.h:220:5: note: candidate template ignored: could not match 'pair<type-parameter-0-0, type-parameter-0-1>' against 'person'

1926 /// This is a helper function for the sort routines.


^ operator<(const pair<_T1, _T2>& __x, const pair<_T1, _T2>& __y)
/usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/bits/stl_pair.h:220:5: note: candidate template ignored: could not match 'pair<type-parameter-0-0, type-parameter-0-1>' against 'person' ^
operator<(const pair<_T1, _T2>& __x, const pair<_T1, _T2>& __y) /usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/bits/stl_iterator.h:297:5: note: candidate template ignored: could not match 'reverse_iterator<type-parameter-0-0>' against 'person'
^ operator<(const reverse_iterator<_Iterator>& __x,
/usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/bits/stl_iterator.h:297:5: note: candidate template ignored: could not match 'reverse_iterator<type-parameter-0-0>' against 'person' ^
operator<(const reverse_iterator<_Iterator>& __x, /usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/bits/stl_iterator.h:347:5: note: candidate template ignored: could not match 'reverse_iterator<type-parameter-0-0>' against 'person'

1927 template<typename _RandomAccessIterator>


^ operator<(const reverse_iterator<_IteratorL>& __x,
/usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/bits/stl_iterator.h:347:5: note: candidate template ignored: could not match 'reverse_iterator<type-parameter-0-0>' against 'person' ^
operator<(const reverse_iterator<_IteratorL>& __x, /usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/bits/stl_vector.h:1421:5: note: candidate template ignored: could not match 'vector<type-parameter-0-0, type-parameter-0-1>' against 'person'
^ operator<(const vector<_Tp, _Alloc>& __x, const vector<_Tp, _Alloc>& __y)
/usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/bits/stl_vector.h:1421:5: note: candidate template ignored: could not match 'vector<type-parameter-0-0, type-parameter-0-1>' against 'person' ^
operator<(const vector<_Tp, _Alloc>& __x, const vector<_Tp, _Alloc>& __y) In file included from person.cpp:2:
^ In file included from /usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/algorithm:62:

1928 void
In file included from person.cpp:2: /usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/bits/stl_algo.h:2242:20: error: invalid operands to binary expression ('person' and 'const person')
In file included from /usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/algorithm:62: while (*__first < __pivot)
In file included from /usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/bits/stl_algo.h:61: ~~~~~~~~ ^ ~~~~~~~
/usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/bits/stl_heap.h:235:35: error: invalid operands to binary expression ('person' and 'person') /usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/bits/stl_algo.h:2283:19: note: in instantiation of function template specialization 'std::__unguarded_partition<__gnu_cxx::__normal_iterator<person *, std::vector<person, std::allocator<person> > >, person>' requested here
if (*(__first + __secondChild) < *(__first + (__secondChild - 1))) return std::__unguarded_partition(__first + 1, __last, *__first);
~~~~~~~~~~~~~~~~~~~~~~~~~~ ^ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ^

1929 __heap_select(_RandomAccessIterator __first,


/usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/bits/stl_heap.h:407:9: note: in instantiation of function template specialization 'std::__adjust_heap<__gnu_cxx::__normal_iterator<person *, std::vector<person, std::allocator<person> > >, long, person>' requested here /usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/bits/stl_algo.h:2315:11: note: in instantiation of function template specialization 'std::__unguarded_partition_pivot<__gnu_cxx::__normal_iterator<person *, std::vector<person, std::allocator<person> > > >' requested here
std::__adjust_heap(__first, __parent, __len, _GLIBCXX_MOVE(__value)); std::__unguarded_partition_pivot(__first, __last);
^ ^
/usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/bits/stl_algo.h:1933:12: note: in instantiation of function template specialization 'std::make_heap<__gnu_cxx::__normal_iterator<person *, std::vector<person, std::allocator<person> > > >' requested here /usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/bits/stl_algo.h:5451:9: note: in instantiation of function template specialization 'std::__introsort_loop<__gnu_cxx::__normal_iterator<person *, std::vector<person, std::allocator<person> > >, long>' requested here
std::make_heap(__first, __middle); std::__introsort_loop(__first, __last,
^ ^
/usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/bits/stl_algo.h:5299:12: note: in instantiation of function template specialization 'std::__heap_select<__gnu_cxx::__normal_iterator<person *, std::vector<person, std::allocator<person> > > >' requested here person.cpp:12:8: note: in instantiation of function template specialization 'std::sort<__gnu_cxx::__normal_iterator<person *, std::vector<person, std::allocator<person> > > >' requested here

1930 _RandomAccessIterator __middle,


std::__heap_select(__first, __middle, __last); std::sort(people.begin(), people.end());
^ ^
/usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/bits/stl_algo.h:2310:24: note: in instantiation of function template specialization 'std::partial_sort<__gnu_cxx::__normal_iterator<person *, std::vector<person, std::allocator<person> > > >' requested here /usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/bits/stl_pair.h:220:5: note: candidate template ignored: could not match 'pair<type-parameter-0-0, type-parameter-0-1>' against 'person'
_GLIBCXX_STD_A::partial_sort(__first, __last, __last); operator<(const pair<_T1, _T2>& __x, const pair<_T1, _T2>& __y)
^ ^
/usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/bits/stl_algo.h:5451:9: note: in instantiation of function template specialization 'std::__introsort_loop<__gnu_cxx::__normal_iterator<person *, std::vector<person, std::allocator<person> > >, long>' requested here /usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/bits/stl_iterator.h:297:5: note: candidate template ignored: could not match 'reverse_iterator<type-parameter-0-0>' against 'person'

1931 _RandomAccessIterator __last)


std::__introsort_loop(__first, __last, operator<(const reverse_iterator<_Iterator>& __x,
^ ^
person.cpp:12:8: note: in instantiation of function template specialization 'std::sort<__gnu_cxx::__normal_iterator<person *, std::vector<person, std::allocator<person> > > >' requested here /usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/bits/stl_iterator.h:347:5: note: candidate template ignored: could not match 'reverse_iterator<type-parameter-0-0>' against 'person'
std::sort(people.begin(), people.end()); operator<(const reverse_iterator<_IteratorL>& __x,
^ ^
/usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/bits/stl_pair.h:220:5: note: candidate template ignored: could not match 'pair<type-parameter-0-0, type-parameter-0-1>' against 'person' /usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/bits/stl_vector.h:1421:5: note: candidate template ignored: could not match 'vector<type-parameter-0-0, type-parameter-0-1>' against 'person'
operator<(const pair<_T1, _T2>& __x, const pair<_T1, _T2>& __y) operator<(const vector<_Tp, _Alloc>& __x, const vector<_Tp, _Alloc>& __y)

1932 {
^ ^
/usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/bits/stl_iterator.h:297:5: note: candidate template ignored: could not match 'reverse_iterator<type-parameter-0-0>' against 'person' In file included from person.cpp:2:
operator<(const reverse_iterator<_Iterator>& __x, In file included from /usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/algorithm:62:
^ /usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/bits/stl_algo.h:2245:19: error: invalid operands to binary expression ('const person' and 'person')
/usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/bits/stl_iterator.h:347:5: note: candidate template ignored: could not match 'reverse_iterator<type-parameter-0-0>' against 'person' while (__pivot < *__last)
operator<(const reverse_iterator<_IteratorL>& __x, ~~~~~~~ ^ ~~~~~~~

1933 std::make_heap(__first, __middle);


^ /usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/bits/stl_pair.h:220:5: note: candidate template ignored: could not match 'pair<type-parameter-0-0, type-parameter-0-1>' against 'const person'
/usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/bits/stl_vector.h:1421:5: note: candidate template ignored: could not match 'vector<type-parameter-0-0, type-parameter-0-1>' against 'person' operator<(const pair<_T1, _T2>& __x, const pair<_T1, _T2>& __y)
operator<(const vector<_Tp, _Alloc>& __x, const vector<_Tp, _Alloc>& __y) ^
^ /usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/bits/stl_iterator.h:297:5: note: candidate template ignored: could not match 'reverse_iterator<type-parameter-0-0>' against 'const person'
In file included from person.cpp:2: operator<(const reverse_iterator<_Iterator>& __x,
In file included from /usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/algorithm:62: ^
In file included from /usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/bits/stl_algo.h:61: /usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/bits/stl_iterator.h:347:5: note: candidate template ignored: could not match 'reverse_iterator<type-parameter-0-0>' against 'const person'

1934 for (_RandomAccessIterator __i = __middle; __i < __last; ++__i)


/usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/bits/stl_heap.h:135:64: error: invalid operands to binary expression ('person' and 'person') operator<(const reverse_iterator<_IteratorL>& __x,
while (__holeIndex > __topIndex && *(__first + __parent) < __value) ^
~~~~~~~~~~~~~~~~~~~~~ ^ ~~~~~~~ /usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/bits/stl_vector.h:1421:5: note: candidate template ignored: could not match 'vector<type-parameter-0-0, type-parameter-0-1>' against 'const person'
/usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/bits/stl_heap.h:247:12: note: in instantiation of function template specialization 'std::__push_heap<__gnu_cxx::__normal_iterator<person *, std::vector<person, std::allocator<person> > >, long, person>' requested here operator<(const vector<_Tp, _Alloc>& __x, const vector<_Tp, _Alloc>& __y)
std::__push_heap(__first, __holeIndex, __topIndex, ^
^ In file included from person.cpp:2:

1935 if (*__i < *__first)


/usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/bits/stl_heap.h:407:9: note: in instantiation of function template specialization 'std::__adjust_heap<__gnu_cxx::__normal_iterator<person *, std::vector<person, std::allocator<person> > >, long, person>' requested here In file included from /usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/algorithm:62:
std::__adjust_heap(__first, __parent, __len, _GLIBCXX_MOVE(__value)); /usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/bits/stl_algo.h:2137:13: error: invalid operands to binary expression ('person' and 'person')
^ if (*__i < *__first)
/usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/bits/stl_algo.h:1933:12: note: in instantiation of function template specialization 'std::make_heap<__gnu_cxx::__normal_iterator<person *, std::vector<person, std::allocator<person> > > >' requested here ~~~~ ^ ~~~~~~~~
std::make_heap(__first, __middle); /usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/bits/stl_algo.h:2211:9: note: in instantiation of function template specialization 'std::__insertion_sort<__gnu_cxx::__normal_iterator<person *, std::vector<person, std::allocator<person> > > >' requested here
^ std::__insertion_sort(__first, __first + int(_S_threshold));
/usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/bits/stl_algo.h:5299:12: note: in instantiation of function template specialization 'std::__heap_select<__gnu_cxx::__normal_iterator<person *, std::vector<person, std::allocator<person> > > >' requested here ^

1936 std::__pop_heap(__first, __middle, __i);


std::__heap_select(__first, __middle, __last); /usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/bits/stl_algo.h:5453:9: note: in instantiation of function template specialization 'std::__final_insertion_sort<__gnu_cxx::__normal_iterator<person *, std::vector<person, std::allocator<person> > > >' requested here
^ std::__final_insertion_sort(__first, __last);

class person
/usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/bits/stl_algo.h:2310:24: note: in instantiation of function template specialization 'std::partial_sort<__gnu_cxx::__normal_iterator<person *, std::vector<person, std::allocator<person> > > >' requested here ^
_GLIBCXX_STD_A::partial_sort(__first, __last, __last); person.cpp:12:8: note: in instantiation of function template specialization 'std::sort<__gnu_cxx::__normal_iterator<person *, std::vector<person, std::allocator<person> > > >' requested here
^ std::sort(people.begin(), people.end());
/usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/bits/stl_algo.h:5451:9: note: in instantiation of function template specialization 'std::__introsort_loop<__gnu_cxx::__normal_iterator<person *, std::vector<person, std::allocator<person> > >, long>' requested here ^

1937 }
std::__introsort_loop(__first, __last,

{
// ...
};

int main()
/usr/include/c++/4.8/bits/stl_algo.h:1935:11: error:
{
invalid operands to binary expression ('person' and 'person')
std::vector<person> people;
if (*__i < *__first)
~~~~ ^ ~~~~~~~~
std::sort(people.begin(), people.end());
}
How to see what went wrong

class person
{
// ...
};

int main()
{
std::vector<person> people;

std::sort(people.begin(), people.end());
}
How to see what went wrong
$ metashell

class person
{
// ...
};

int main()
{
std::vector<person> people;

std::sort(people.begin(), people.end());
}
How to see what went wrong
$ metashell
/* … */
>

class person
{
// ...
};

int main()
{
std::vector<person> people;

std::sort(people.begin(), people.end());
}
How to see what went wrong
$ metashell
/* … */
> #include "person.cpp"

class person
{
// ...
};

int main()
{
std::vector<person> people;

std::sort(people.begin(), people.end());
}
How to see what went wrong
$ metashell
/* … */
> #include "person.cpp"
/usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/bits/stl_algo.h:1935:11:
fatal error: invalid operands to binary expression ('person' and 'person')
>

class person
{
// ...
};

int main()
{
std::vector<person> people;

std::sort(people.begin(), people.end());
}
How to see what went wrong
$ metashell
/* … */
> #include "person.cpp"
/usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/bits/stl_algo.h:1935:11:
fatal error: invalid operands to binary expression ('person' and 'person')
>

class person
{
// ...
};

int main()
{
std::vector<person> people;

std::sort(people.begin(), people.end());
}
How to see what went wrong
$ metashell
/* … */
> #include "person.cpp"
/usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/bits/stl_algo.h:1935:11:
fatal error: invalid operands to binary expression ('person' and 'person')
>

class person
{
// ...
};

int main()
{
std::vector<person> people;

// std::sort(people.begin(), people.end());
}
How to see what went wrong
$ metashell
/* … */
> #include "person.cpp"
/usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/bits/stl_algo.h:1935:11:
fatal error: invalid operands to binary expression ('person' and 'person')
> #include "person.cpp"
>

class person
{
// ...
};

int main()
{
std::vector<person> people;

// std::sort(people.begin(), people.end());
}
How to see what went wrong
$ metashell
/* … */
> #include "person.cpp"
/usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/bits/stl_algo.h:1935:11:
fatal error: invalid operands to binary expression ('person' and 'person')
> #include "person.cpp"
> #include <metashell/instantiate_expression.hpp>
>

class person
{
// ...
};

int main()
{
std::vector<person> people;

// std::sort(people.begin(), people.end());
}
How to see what went wrong
$ metashell
/* … */
> #include "person.cpp"
/usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/bits/stl_algo.h:1935:11:
fatal error: invalid operands to binary expression ('person' and 'person')
> #include "person.cpp"
> #include <metashell/instantiate_expression.hpp>
> std::vector<person> people;
>

class person
{
// ...
};

int main()
{
std::vector<person> people;

// std::sort(people.begin(), people.end());
}
How to see what went wrong
$ metashell
/* … */
> #include "person.cpp"
/usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/bits/stl_algo.h:1935:11:
fatal error: invalid operands to binary expression ('person' and 'person')
> #include "person.cpp"
> #include <metashell/instantiate_expression.hpp>
> std::vector<person> people;
>

class person
{
// ...
};

int main()
{
std::vector<person> people;

// std::sort(people.begin(), people.end());
}
How to see what went wrong
$ metashell
/* … */
> #include "person.cpp"
/usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/bits/stl_algo.h:1935:11:
fatal error: invalid operands to binary expression ('person' and 'person')
> #include "person.cpp"
> #include <metashell/instantiate_expression.hpp>
> std::vector<person> people;
> #msh mdb METASHELL_INSTANTIATE_EXPRESSION( std::sort(people.begin(), people.end()) )

class person
{
// ...
};

int main()
{
std::vector<person> people;

// std::sort(people.begin(), people.end());
}
How to see what went wrong
$ metashell
/* … */
> #include "person.cpp"
/usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/bits/stl_algo.h:1935:11:
fatal error: invalid operands to binary expression ('person' and 'person')
> #include "person.cpp"
> #include <metashell/instantiate_expression.hpp>
> std::vector<person> people;
> #msh mdb METASHELL_INSTANTIATE_EXPRESSION( std::sort(people.begin(), people.end()) )
For help, type "help".
Metaprogram started
(mdb)

class person
{
// ...
};

int main()
{
std::vector<person> people;

// std::sort(people.begin(), people.end());
}
How to see what went wrong
$ metashell
/* … */
> #include "person.cpp"
/usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/bits/stl_algo.h:1935:11:
fatal error: invalid operands to binary expression ('person' and 'person')
> #include "person.cpp"
> #include <metashell/instantiate_expression.hpp>
> std::vector<person> people;
> #msh mdb METASHELL_INSTANTIATE_EXPRESSION( std::sort(people.begin(), people.end()) )
For help, type "help".
Metaprogram started
(mdb)

1926 /// This is a helper function for the sort routines.


1927class person _RandomAccessIterator>
template<typename
1928{ void
1929 __heap_select(_RandomAccessIterator __first,
1930 // ... _RandomAccessIterator __middle,
1931}; _RandomAccessIterator __last)
1932 {
1933 std::make_heap(__first, __middle);
1934int for
main()
(_RandomAccessIterator __i = __middle; __i < __last; ++__i)
1935{ if (*__i < *__first)
1936 std::__pop_heap(__first, __middle, __i);
1937 std::vector<person>
} people;

// std::sort(people.begin(), people.end());
}
How to see what went wrong
$ metashell
/* … */
> #include "person.cpp"
/usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/bits/stl_algo.h:1935:11:
fatal error: invalid operands to binary expression ('person' and 'person')
> #include "person.cpp"
> #include <metashell/instantiate_expression.hpp>
> std::vector<person> people;
> #msh mdb METASHELL_INSTANTIATE_EXPRESSION( std::sort(people.begin(), people.end()) )
For help, type "help".
Metaprogram started
(mdb)

1926 /// This is a helper function for the sort routines.


1927class person _RandomAccessIterator>
template<typename
1928{ void
1929 __heap_select(_RandomAccessIterator __first,
1930 // ... _RandomAccessIterator __middle,
1931}; _RandomAccessIterator __last)
1932 {
1933 std::make_heap(__first, __middle);
1934int for
main()
(_RandomAccessIterator __i = __middle; __i < __last; ++__i)
1935{ if (*__i < *__first)
1936 std::__pop_heap(__first, __middle, __i);
1937 std::vector<person>
} people;

// std::sort(people.begin(), people.end());
}
How to see what went wrong
$ metashell
/* … */
> #include "person.cpp"
/usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/bits/stl_algo.h:1935:11:
fatal error: invalid operands to binary expression ('person' and 'person')
> #include "person.cpp"
> #include <metashell/instantiate_expression.hpp>
> std::vector<person> people;
> #msh mdb METASHELL_INSTANTIATE_EXPRESSION( std::sort(people.begin(), people.end()) )
For help, type "help".
Metaprogram started
(mdb) rbreak __heap_select

1926 /// This is a helper function for the sort routines.


1927class person _RandomAccessIterator>
template<typename
1928{ void
1929 __heap_select(_RandomAccessIterator __first,
1930 // ... _RandomAccessIterator __middle,
1931}; _RandomAccessIterator __last)
1932 {
1933 std::make_heap(__first, __middle);
1934int for
main()
(_RandomAccessIterator __i = __middle; __i < __last; ++__i)
1935{ if (*__i < *__first)
1936 std::__pop_heap(__first, __middle, __i);
1937 std::vector<person>
} people;

// std::sort(people.begin(), people.end());
}
How to see what went wrong
$ metashell
/* … */
> #include "person.cpp"
/usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/bits/stl_algo.h:1935:11:
fatal error: invalid operands to binary expression ('person' and 'person')
> #include "person.cpp"
> #include <metashell/instantiate_expression.hpp>
> std::vector<person> people;
> #msh mdb METASHELL_INSTANTIATE_EXPRESSION( std::sort(people.begin(), people.end()) )
For help, type "help".
Metaprogram started
(mdb) rbreak __heap_select
Breakpoint "__heap_select" will stop the execution on 2 locations
(mdb)
class person
{
// ...
};

int main()
{
std::vector<person> people;

// std::sort(people.begin(), people.end());
}
How to see what went wrong
$ metashell
/* … */
> #include "person.cpp"
/usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/bits/stl_algo.h:1935:11:
fatal error: invalid operands to binary expression ('person' and 'person')
> #include "person.cpp"
> #include <metashell/instantiate_expression.hpp>
> std::vector<person> people;
> #msh mdb METASHELL_INSTANTIATE_EXPRESSION( std::sort(people.begin(), people.end()) )
For help, type "help".
Metaprogram started
(mdb) rbreak __heap_select
Breakpoint "__heap_select" will stop the execution on 2 locations
(mdb) c
class person
{
// ...
};

int main()
{
std::vector<person> people;

// std::sort(people.begin(), people.end());
}
How to see what went wrong
$ metashell
/* … */
> #include "person.cpp"
/usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/bits/stl_algo.h:1935:11:
fatal error: invalid operands to binary expression ('person' and 'person')
> #include "person.cpp"
> #include <metashell/instantiate_expression.hpp>
> std::vector<person> people;
> #msh mdb METASHELL_INSTANTIATE_EXPRESSION( std::sort(people.begin(), people.end()) )
For help, type "help".
Metaprogram started
(mdb) rbreak __heap_select
Breakpoint "__heap_select" will stop the execution on 2 locations
(mdb) c
Breakpoint "__heap_select" class
reached person
std::__heap_select<__gnu_cxx::__normal_iterator<person *, std::vector<person, std::all
{
ocator<person> > > > (TemplateInstantiation from /usr/lib/gcc/x86_64-linux-gnu/4.8/../
../../../include/c++/4.8/bits/stl_algo.h:5299:7)
(mdb)
// ...
};

int main()
{
std::vector<person> people;

// std::sort(people.begin(), people.end());
}
How to see what went wrong
$ metashell
/* … */
> #include "person.cpp"
/usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/bits/stl_algo.h:1935:11:
fatal error: invalid operands to binary expression ('person' and 'person')
> #include "person.cpp"
> #include <metashell/instantiate_expression.hpp>
> std::vector<person> people;
> #msh mdb METASHELL_INSTANTIATE_EXPRESSION( std::sort(people.begin(), people.end()) )
For help, type "help".
Metaprogram started
(mdb) rbreak __heap_select
Breakpoint "__heap_select" will stop the execution on 2 locations
(mdb) c
Breakpoint "__heap_select" class
reached person
std::__heap_select<__gnu_cxx::__normal_iterator<person *, std::vector<person, std::all
{
ocator<person> > > > (TemplateInstantiation from /usr/lib/gcc/x86_64-linux-gnu/4.8/../
../../../include/c++/4.8/bits/stl_algo.h:5299:7)
(mdb) bt
// ...
};

int main()
{
std::vector<person> people;

// std::sort(people.begin(), people.end());
}
How to see what went wrong
$ metashell
/* … */
> #include "person.cpp"
/usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/bits/stl_algo.h:1935:11:
fatal error: invalid operands to binary expression ('person' and 'person')
> #include "person.cpp"
> #include <metashell/instantiate_expression.hpp>
> std::vector<person> people;
> #msh mdb METASHELL_INSTANTIATE_EXPRESSION( std::sort(people.begin(), people.end()) )
For help, type "help".
Metaprogram started
(mdb) rbreak __heap_select
Breakpoint "__heap_select" will stop the execution on 2 locations
(mdb) c
Breakpoint "__heap_select" class
reached person
std::__heap_select<__gnu_cxx::__normal_iterator<person *, std::vector<person, std::all
{
ocator<person> > > > (TemplateInstantiation from /usr/lib/gcc/x86_64-linux-gnu/4.8/../
../../../include/c++/4.8/bits/stl_algo.h:5299:7)
(mdb) bt
// ...
};
#0 std::__heap_select<__gnu_cxx::__normal_iterator<person *, std::vector<person, std::
allocator<person> > > > (TemplateInstantiation from /usr/lib/gcc/x86_64-linux-gnu/4.8/
../../../../include/c++/4.8/bits/stl_algo.h:5299:7)
int main()
#1 std::partial_sort<__gnu_cxx::__normal_iterator<person *, std::vector<person, std::a
llocator<person> > > > (TemplateInstantiation from /usr/lib/gcc/x86_64-linux-gnu/4.8/.
{
./../../../include/c++/4.8/bits/stl_algo.h:2310:8)
std::vector<person> people;
#2 std::__introsort_loop<__gnu_cxx::__normal_iterator<person *, std::vector<person, st
d::allocator<person> > >, long> (TemplateInstantiation from /usr/lib/gcc/x86_64-linux-
gnu/4.8/../../../../include/c++/4.8/bits/stl_algo.h:5451:4)
// std::sort(people.begin(),
#3 std::sort<__gnu_cxx::__normal_iterator<person people.end());
*, std::vector<person, std::allocator
<person> > > > (TemplateInstantiation from <stdin>:2:26)
}
#4 METASHELL_INSTANTIATE_EXPRESSION( std::sort(people.begin(), people.end()) )
How to see what went wrong
$ metashell
/* … */
> #include "person.cpp"
/usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/bits/stl_algo.h:1935:11:
fatal error: invalid operands to binary expression ('person' and 'person')
> #include "person.cpp"
> #include <metashell/instantiate_expression.hpp>
> std::vector<person> people;
> #msh mdb METASHELL_INSTANTIATE_EXPRESSION( std::sort(people.begin(), people.end()) )
For help, type "help".
Metaprogram started
(mdb) rbreak __heap_select
Breakpoint "__heap_select" will stop the execution on 2 locations
(mdb) c
Breakpoint "__heap_select" class
reached person
std::__heap_select<__gnu_cxx::__normal_iterator<person *, std::vector<person, std::all
{
ocator<person> > > > (TemplateInstantiation from /usr/lib/gcc/x86_64-linux-gnu/4.8/../
../../../include/c++/4.8/bits/stl_algo.h:5299:7)
(mdb) bt
// ...
};
#0 std::__heap_select<__gnu_cxx::__normal_iterator<person *, std::vector<person, std::
allocator<person> > > > (TemplateInstantiation from /usr/lib/gcc/x86_64-linux-gnu/4.8/
../../../../include/c++/4.8/bits/stl_algo.h:5299:7)
int main()
#1 std::partial_sort<__gnu_cxx::__normal_iterator<person *, std::vector<person, std::a
llocator<person> > > > (TemplateInstantiation from /usr/lib/gcc/x86_64-linux-gnu/4.8/.
{
./../../../include/c++/4.8/bits/stl_algo.h:2310:8)
std::vector<person> people;
#2 std::__introsort_loop<__gnu_cxx::__normal_iterator<person *, std::vector<person, st
d::allocator<person> > >, long> (TemplateInstantiation from /usr/lib/gcc/x86_64-linux-
gnu/4.8/../../../../include/c++/4.8/bits/stl_algo.h:5451:4)
// std::sort(people.begin(),
#3 std::sort<__gnu_cxx::__normal_iterator<person people.end());
*, std::vector<person, std::allocator
<person> > > > (TemplateInstantiation from <stdin>:2:26)
}
#4 METASHELL_INSTANTIATE_EXPRESSION( std::sort(people.begin(), people.end()) )
It all depends on a Clang patch

MDB Scripted analysis Callgrind view


It all depends on a Clang patch

MDB Scripted analysis Callgrind view

Templight
It all depends on a Clang patch

MDB Scripted analysis Callgrind view

Templight

Clang patch
It all depends on a Clang patch

MDB Scripted analysis Callgrind view

Templight

Clang patch

http://reviews.llvm.org/D5767
Q&A

You might also like