vendredi 25 septembre 2020

Why the implementation of declval in libstdc++-v3 looks so complicated?

code snippet 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 simple as:

template <typename T> T declval();

Here is my test code:

// filename: test.cpp
#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
  1. Why the implementation in libstdc++-v3 looks so complicated?
  2. What does the "template 1" do?
  3. Why __declval need an parameter(int/long)?
  4. Why "template 1"(int) and "template 2"(long) have different parameter type?
  5. Are there any problems with my simple implementation?

Aucun commentaire:

Enregistrer un commentaire