The code below comes from libstdc++-v3 std::type_traits
, which is an implementation of std::declval
:
template<typename _Tp, typename _Up = _Tp&&> // template 1
_Up
__declval(int);
template<typename _Tp> // template 2
_Tp
__declval(long);
template<typename _Tp> // template 3
auto declval() noexcept -> decltype(__declval<_Tp>(0));
But I think I can implement declval
as simply:
template <typename T> T declval();
Here is my test code:
#include <iostream>
using namespace std;
struct C {
C() = delete;
int foo() { return 0; }
};
namespace test {
template <typename T> T declval();
};// namespace test
int main() {
decltype(test::declval<C>().foo()) n = 1;
cout << n << endl;
}
Build and run commands are:
g++ -std=c++11 ./test.cpp
./a.out
- Why does the implementation in libstdc++-v3 look so complicated?
- What does template 1 in the first snippet do?
- Why does
__declval
need a parameter (int
/long
)? - Why do template 1 (
int
) and template 2 (long
) have different parameter types? - Are there any problems with my simple implementation?
_Tp&&
? – Plunkett