【发布时间】:2017-01-12 14:18:58
【问题描述】:
处理某些类型需要使用 .运算符,而其他人使用 -> 运算符。
最好为 .运算符并让调用者包装类型,如下面的代码示例所示。
来自 C# 背景,我不习惯遇到这个特殊问题。
#include <iostream>
#include <string>
#include <vector>
#include <memory>
template<class T>
class container{
public:
void add(T element){
elements_.push_back(std::move(element));
}
void process(){
for(auto& a: elements_){
a.print();
}
}
private:
std::vector<T> elements_;
};
class printable{
public:
void print(){
std::cout << "Print\n";
}
};
template<class T>
class printable_forwarder{
public:
printable_forwarder(T element): element_{std::move(element)}{
}
void print(){
element_->print();
}
private:
T element_;
};
int main()
{
container<printable> c1;
c1.add(printable{});
c1.process();
container<printable_forwarder<std::shared_ptr<printable>>> c2;
std::shared_ptr<printable> sp{std::make_shared<printable>()};
c2.add(printable_forwarder<decltype(sp)>{sp});
c2.process();
}
这样看起来更好吗?
#include <iostream>
#include <string>
#include <memory>
#include <type_traits>
#include <vector>
template<typename T>
class dereference
{
public:
inline static T& get(T& value){
return value;
}
};
template<typename T>
class dereference<T*>
{
public:
inline static typename std::add_lvalue_reference<typename std::remove_pointer<T>::type>::type get(T* value){
return *value;
}
};
template<typename T>
class dereference<std::shared_ptr<T>>
{
public:
inline static T& get(std::shared_ptr<T> value){
return *value.get();
}
};
template<class T>
class container{
public:
void add(T const& v){
items_.push_back(v);
}
void print_all(){
for(auto& a: items_){
dereference<T>::get(a).print();
}
}
private:
std::vector<T> items_;
};
struct printable{
void print(){
std::cout << "Printing\n";
}
};
int main()
{
container<printable> c1;
c1.add(printable{});
c1.print_all();
container<std::shared_ptr<printable>> c2;
c2.add( std::shared_ptr<printable>(new printable{}));
c2.print_all();
}
【问题讨论】:
-
你只需要等到我们能够重载
operator.,就像在 C++54 中一样。有一个提案,我相信 Bjarne 参与其中。 -
当你调用你的泛型函数/创建泛型对象或其他什么时,你不能只引用指针吗?无需过度设计。
-
你不能因为你没有指定回调
-
我不明白你要解决什么问题,但我不得不承认我也不明白你的解决方案;)。正如乔治所说,只需在调用函数之前取消引用指针......
-
如果你创建一个容器
> 例如打印调用失败。
标签: c++ templates generic-programming