C模板函数获取默认的默认值
我在C中打了一个真正的脑保肝器,以前从来没有发生过.
问题的要点是,在调用我的(模板)函数时,我已经定义了默认值的参数将其值加扰.只有当我使用默认值调用该函数时才会发生. 我的模板函数是这样声明的: template <typename T> vector2<T> transform(vector2<T> const &vec,matrix4<T> const &m,T z = T(0),T w = T(1)); 后来,在同一个标??题中,定义如下: template <typename T> inline vector2<T> transform(vector2<T> const &vec,T z,T w) { vector4<T> res = m * vector4<T>(vec.x,vec.y,z,w); return vector2<T>(res.x,res.y); } 现在当我使用默认值(transform(vector2< double>(0,1),view_transform))调用它时))我没有得到我期望的值.使用VC调试器进行转换,我看到z和w具有“有趣”值(根据我的经验意味着某些东西没有被正确初始化). 示例有趣的值将是:0.0078125000000000000和2.104431116947e-317#DEN 现在我已经尝试找到C FAQ Lite的答案,搜索它;甚至试图用舒伯特冷静自己,但我不能为我的生活弄清楚.我猜这很简单,我怀疑它是在工作中的某种模板tomfoolery. 有没有办法获得我期望和想要的默认值,为什么要这样做呢? 编辑1: 如果我改变调用,那么它使用浮点代码(transform(vector2< float>(0,view_transform)),问题消失了.看来这只有在T =双倍时才会发生. 编辑2: 只有当我有两个专业的double和float时才会发生.如果我在一个地方使用浮动专业化,那么双重专业化将会产生奇怪的默认值.如果我更改所有的函数调用的地方,所以它使用了两倍的问题“消失”.我仍然不明白为什么,它就像使用错误的偏移或设置z和w时的东西. 编辑3: 来自C Crypt的故事: #include <sgt/matrix4.hpp> int main(int argc,char *argv[]) { sgt::matrix4<double> m0( 2,1,2,1); m0 *= m0; sgt::vector2<double> blah0 = sgt::transform(sgt::vector2<double>(1,0),m0); sgt::matrix4<float> m1( 2,1); m1 *= m1; sgt::vector2<float> blah1 = sgt::transform(sgt::vector2<float>(1,m1); printf("%f",blah0.x); printf("%f",blah1.x); } 在matrix4.hpp中 // ... template <typename T> vector2<T> transform(vector2<T> const &vec,T w = T(1)); template <typename T> inline vector2<T> transform(vector2<T> const &vec,T w) { vector4<T> res = m * vector4<T>(vec.x,w); return vector2<T>(res.x,res.y); } // ... 如果我运行它,双精度的默认参数是正确的,但是float版本的默认参数为零(0.000000),尽管如此,它仍然不是z = 0和w = 1. 编辑4: 做了Connect issue. 解决方法
以下在Dev Studio中失败:
#include "stdafx.h" #include <vector> #include <iostream> template <typename T> std::vector<std::vector<T> > transform(std::vector<std::vector<T> > const &vec,std::vector<std::vector<std::vector<std::vector<T> > > > const &m,T w = T(1)); template <typename T> std::vector<std::vector<T> > transform(std::vector<std::vector<T> > const &vec,T w) { std::cout << "Z" << z << "n"; std::cout << "W" << w << "n"; return vec; } int _tmain(int argc,_TCHAR* argv[]) { std::vector<std::vector<int> > xi; std::vector<std::vector<std::vector<std::vector<int> > > > mi; transform(xi,mi); std::vector<std::vector<float> > xf; std::vector<std::vector<std::vector<std::vector<float> > > > mf; transform(xf,mf); std::vector<std::vector<double> > xd; std::vector<std::vector<std::vector<std::vector<double> > > > md; transform(xd,md); } 输出: Z0 W1 Z0 W1.4013e-045 Z2.122e-314 W3.60689e-305 所以我想它不能像预期的那样工作! 如果删除预声明并将默认参数放在模板函数中,则它将按预期工作. #include "stdafx.h" #include <vector> #include <iostream> template <typename T> std::vector<std::vector<T> > transform(std::vector<std::vector<T> > const &vec,std::vector<std::vector<std::vector<std::vector<T> > > > const &m T z = T(0),T w = T(1)) { std::cout << "Z" << z << "n"; std::cout << "W" << w << "n"; return vec; } int _tmain(int argc,md); } 这样可以预期. 好.不是从我阅读的标准,这应该按预期工作: 使用n2521
段落的粗体部分似乎(对我来说),表示由于默认参数创建的每个专业化将被使用时隐式地实例化到翻译单元中. 第11段:
表示即使默认参数是模板参数,它们也将被正确实例化. 我希望我能正确地解释. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |