decltype不从函数中推导出指针,导致调用错误的特征类

时间:2013-01-10 13:40:50

标签: c++ templates

#include <iostream>
#include <vector>
#include <memory>
#include <type_traits>
#include <string>
#include <algorithm>
#include <functional>
#include <iterator>

using namespace std;

class person{
public:
    person(){
        cout << "default ctor\n";
    };
    person(string const & name) : name(name){
        cout << "in name ctor\n";
    }
    person(person const & other) : name(other.name){
        cout << "copy ctor\n";
    }
    person& operator = (person other){
        cout << "copy assign oper\n";
        std::swap(name,other.name);
        return *this;
    }
    person(person&& other) : name(std::move(other.name)){
        cout << "Move ctor\n";
    }
    person& operator = (person && other){
        name = std::move(other.name);
        cout << "Move assign operator\n";
        return *this;
    }
    void print() const{
        cout << name << endl;
    }
private:
    string name;
};

template<class T>
class get_unwrapped{
public:
    T& get(T& t){
        return t;
    }
};


template<class T>
class get_unwrapped<T*>{
public:
    T& get(T* t){
        return *t;
    }
};

template<class T>
class get_unwrapped<shared_ptr<T>>{
public:
    T& get(shared_ptr<T>& t){
        return *t;
    }
};

template<class T>
void print_all(T&& elements){    
    for(auto it = std::begin(elements); it != std::end(elements); ++it){
        get_unwrapped<decltype(*it)> unwrapper;
        auto &result = unwrapper.get(*it);
        result.print();
    }
}


int main()
{

    vector<person*> v;

    v.reserve(3);
    v.push_back(new person("Blair"));
    v.push_back(new person("Esther"));

    print_all(v);


    return 0;
}

2 个答案:

答案 0 :(得分:0)

为什么不简单地使用模板?

template<class T>
T& get_unwrapped(T& t){
  return t;
}

template<class T>
T& get_unwrapped(T* t){
  return *t;
}

template<class T>
T& get_unwrapped(shared_ptr<T>& t){
  return *t;
}

// ...
auto &result = get_unwrapped(*it);
result.print();

答案 1 :(得分:0)

迭代器的

operator*返回引用类型,因此指针特化不匹配。

如果你这样说,你的代码就可以了:

get_unwrapped< typename std::remove_reference<decltype(*it)>::type > unwrapper;

你可以尝试一下:

std::cout << std::is_same< decltype(*it), person*&>::value;

打印1