Compile-Time Tools For Generic Programming in C++ - Abel Sinkovics - CppCon 2015
Compile-Time Tools For Generic Programming in C++ - Abel Sinkovics - CppCon 2015
programming in C++
Ábel Sinkovics
Morgan Stanley
Generic programming
foo<bar<int>> x;
Using templates
template <class T>
class foo { … };
foo<bar<int>> x;
Compiler
Using templates
template <class T>
class foo { … };
foo<bar<int>> x;
Compiler
Object
code
Using templates
template <class T>
class foo { … };
foo<bar<int>> x;
Compiler
Object
code
Error report
…
…
…
…
…
…
Using templates
template <class T>
class foo { … };
foo<bar<int>> x;
Compiler
Object
code
Error report
…
…
…
…
…
…
Using templates
template <class T>
class foo { … };
foo<bar<int>> x;
Compiler
Object
code
Error report
…
…
…
…
…
…
Using templates
template <class T>
class foo { … };
foo<bar<int>> x;
Compiler
Object
code
Error report
…
…
…
…
…
…
Using templates
template <class T>
class foo { … };
foo<bar<int>> x;
Compiler
Object
code
Error report
…
…
…
…
…
…
Using templates
template <class T>
class foo { … };
foo<bar<int>> x;
Compiler
Object
code
Error report
…
…
…
…
…
…
Using templates
template <class T>
class foo { … };
foo<bar<int>> x;
Compiler
Object
code
Error report
…
…
…
…
…
…
Using templates
template <class T>
class foo { … };
foo<bar<int>> x;
template
Compiler Compiler
foo<bar<int>>
template Object
code
Error report
…
…
…
…
…
…
Template metaprogrammers
foo<bar<int>>
template
Template metaprogrammers
foo<bar<int>>
template
template
template
template template
template
template template
Template metaprogrammers
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"
#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
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();
}
int main()
{
std::cout << typeid(a<int>::handle).name();
}
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"
#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"
#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
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>
int main()
{
}
What is the type of...? #2
#include <a.hpp>
int main()
{
fun<double>();
}
What is the type of...? #2
#include <a.hpp>
int main()
{
fun<double>();
}
Approaches
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>
int main()
{
fun<double>();
}
IDEs
#include <a.hpp>
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
$ 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
int main()
{
f(3.1415);
}
What is the type of...? #3
int main()
{
f(3.1415);
}
What is the type of...? #3
int main()
{
f(3.1415);
double d = 1.0;
f(d);
}
What is the type of...? #3
int main()
{
f(3.1415);
double d = 1.0;
f(d);
}
What is the type of...? #3
Deduced types
int main()
{
f(3.1415);
double d = 1.0;
f(d);
}
What is the type of...? #3
Deduced types
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
main3.o.trace.pbf
Templight
main3.o.trace.pbf
main3.o.trace.pbf
main3.o.trace.pbf
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>
sum(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
Summarising numbers
sum.hpp
#include <type_traits>
sum(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
Summarising numbers
sum.hpp
#include <type_traits>
sum(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
Summarising numbers
sum.hpp
#include <type_traits>
sum(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
Summarising numbers
sum.hpp
#include <type_traits>
sum(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
Summarising numbers
sum.hpp
#include <type_traits>
sum(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
Summarising numbers
sum.hpp
#include <type_traits>
sum(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
Summarising numbers
sum.hpp
#include <type_traits>
sum(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
Summarising numbers
sum.hpp
#include <type_traits>
sum(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
Summarising numbers
sum.hpp
#include <type_traits>
sum(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
Summarising numbers
sum.hpp
#include <type_traits>
sum(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
An STL example
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
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
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
. . .
. . .
When things go wrong
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'
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);
~~~~~~~~~~~~~~~~~~~~~~~~~~ ^ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ^
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, ~~~~~~~ ^ ~~~~~~~
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)
// 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)
// 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
// 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
Templight
It all depends on a Clang patch
Templight
Clang patch
It all depends on a Clang patch
Templight
Clang patch
http://reviews.llvm.org/D5767
Q&A