Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/templates/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 更好的转换功能_C++_Templates - Fatal编程技术网

C++ 更好的转换功能

C++ 更好的转换功能,c++,templates,C++,Templates,我在C++0x框架中有各种各样的类,我想编写函数在其中一些类之间进行转换。例如: struct Foo { float v; }; struct Bar { int i; }; struct Tar { float p, q; }; void Convert(const Foo& x, Bar& y) { y.i = static_cast<int>(x.v); } void Convert(const Tar& x, Foo& y) { y.v =

我在C++0x框架中有各种各样的类,我想编写函数在其中一些类之间进行转换。例如:

struct Foo { float v; };
struct Bar { int i; };
struct Tar { float p, q; };

void Convert(const Foo& x, Bar& y) { y.i = static_cast<int>(x.v); }
void Convert(const Tar& x, Foo& y) { y.v = x.p + x.q; }
structfoo{float v;};
结构条{int i;};
结构Tar{float p,q;};
void Convert(const Foo&x,Bar&y){y.i=static_cast(x.v);}
void Convert(const Tar&x,Foo&y){y.v=x.p+x.q;}
这只是一个例子。有相当多的“小”类。并不是所有的转换函数都有意义

此外,还有一些类的行为本质上类似于STL容器,应该“继承”这些转换函数

void Convert(const std::vector<Foo>& cx, std::vector<Bar>& cy) { ... }
void Convert(const std::vector<Tar>& cx, std::vector<Bar>& cy) { ... }
void转换(const std::vector&cx,std::vector&cy){…}
void Convert(const std::vector&cx,std::vector&cy){…}
不,我正在寻找一种简单的方法来定义这些函数。我试过:

template<typename X, typename Y>
void Convert(const std::vector<X>& cx, std::vector<Y>& cy) {
   cy.resize(cx.size());
   for(std::size_t i=0; i<cx.size(); i++) {
     Convert(cx[i], cy[i]);
   }
}
模板
无效转换(常量std::vector和cx,std::vector和cy){
cy.resize(cx.size());

对于(std::size\u t i=0;i您是否考虑过使用系数:

struct Bar {
   int i;

   explicit Bar(Foo const &f) : i(static_cast<int>(f.v)) {}
};
结构栏{
int i;
显式条(Foo-const&f):i(静态_-cast(f.v)){}
};
然后你可以做:

Bar x = static_cast<Bar>(some_foo);
Bar x=静态演员阵容(一些演员);
您是否真的希望使该向量显式化可能存在疑问。如果您消除它(允许隐式转换),转换向量将变得微不足道:

std::vector<foo> foos;

// code to populate foos ...

std::vector<Bar> bars((foos.begin()), foos.end());
std::vector foos;
//填充foos的代码。。。
向量条((foos.begin()),foos.end());

至于是否将其显式化,问题是您是否可能意外地从Foo转换为Bar,从而让您真正不想发生的事情发生。这是转换为
bool
之类的事情的一个非常常见的问题,但从一个用户定义类型转换为另一个类型的问题要少得多r、 在这种情况下,关闭
explicit
会很方便而且相当安全。

为什么不简单地使用构造函数呢

explicit Bar(const Foo& x) : i(static_cast<int>(x.v)) {}
explicit Bar(const Foo&x):i(static_cast(x.v)){

由于返回值优化您不需要使用out参数,只需使用返回值:

void Convert(const X& x, Y& y);
变成:

Y Convert(const X& x);
现在你可以在表达式中使用它了

也可以考虑使用<强>转换构造函数<强>或>强>转换运算符< /强>代替:

Y::Y(const X&);
X::operator Y();
这些将允许类型之间的隐式转换(如果这是您想要的-否则您可以将它们声明为显式)

要处理STL容器,请使用迭代器范围:

template<class FwdIterator>
Y Convert(FwdIterator begin, FwdIterator end);
模板
Y转换(FwdIterator开始,FwdIterator结束);
在这种样式中,它不仅与所有STL容器兼容,还与原始指针范围兼容

还要注意,如果声明隐式转换构造函数或转换运算符,则可以使用std::copy:

vector<X> xs = ...;
vector<Y> ys;
copy(xs.begin(), xs.end(), back_inserter(ys.begin()));
向量xs=。。。; 向量ys; 复制(xs.begin(),xs.end(),back_inserter(ys.begin());

当将元素从xs转换为ys时,这将隐式调用用户定义的转换。

实际上,我发现了如何执行此操作

template<typename Y, typename X>
std::vector<Y> ConvertTo(const std::vector<X>& cx) {
   std::vector<Y> cy(cx.size());
   for(std::size_t i=0; i<cx.size(); i++) {
     cy[i] = Convert(cx[i]);
   }
   return cy;
}
模板
std::vector ConvertTo(const std::vector&cx){
std::vector cy(cx.size());

对于(std::size\u t i=0;我已尝试过
转换(cx,cy)
?我想知道的是,为什么你需要这么多小的类和小的转换函数?对我来说,这种设计似乎有些奇怪。@Danvil:我没有更改你的任何代码,它工作得很好。@Danvil:至于容器,
boost::transform\u iterator
会让它们变得非常简单。我想补充一点typedefs可以让您的生活更轻松。例如…typedef std::vector vecint;vecint a={4,2,1};这不会转换容器,并且他可能无法修改类。不过这是一个有效的建议。一个类型可能有多个转换。因此Y convert(const X&X);不起作用。您是指多个结果类型吗?(输入参数使函数重载)您可以通过以下方式生成不同的结果类型:(1)使其成为类型参数
Convert(x)
,或;(2)将类型添加到函数标识符,即
Convert_Y(x)
;或(3)使用转换构造函数或转换运算符。
template<class FwdIterator>
Y Convert(FwdIterator begin, FwdIterator end);
vector<X> xs = ...;
vector<Y> ys;
copy(xs.begin(), xs.end(), back_inserter(ys.begin()));
template<typename Y, typename X>
std::vector<Y> ConvertTo(const std::vector<X>& cx) {
   std::vector<Y> cy(cx.size());
   for(std::size_t i=0; i<cx.size(); i++) {
     cy[i] = Convert(cx[i]);
   }
   return cy;
}
std::vector<Y> cy = ConvertTo<Y>(cx);