如何分解以下代码,以便在T = double和T = float中执行循环?我读过关于可变模板的文章,但我不知道如何在这种情况下应用它:
int main(int argc, char* argv[])
{
ofstream writeDat;
vector<int> nValues = {26,51,101,201};
for(int i = 0; i< 4; i++){
int N = nValues[i];
typedef float T ;
Matrix<T> a(N,N);
Matrix<T> b(N,3);
Matrix<T> x = Problem2<T>(N);
string sFloat = "2/" + to_string(N) + "Float"+".dat";
writeDat.open(sFloat);
for(int i =1; i<N ; i++)
writeDat << i << " " << x(i,1)<<endl;
writeDat << N <<" "<< x(N,1)<< endl;
writeDat.close();
}
for(int i = 0; i< 4; i++){
int N = nValues[i];
typedef double T ;
Matrix<T> a(N,N);
Matrix<T> b(N,3);
Matrix<T> x = Problem2<T>(N);
string s = "2/" + to_string(N) + "Double"+".dat";
writeDat.open(s);
for(int i =1; i<N ; i++)
writeDat << i << " " << x(i,1)<<endl;
writeDat << N <<" "<< x(N,1)<< endl;
writeDat.close();
}
return 0;
}发布于 2018-09-24 16:00:39
使用可变扩展来调用包含复制逻辑的模板函数(或可变lambda):
#include<fstream>
#include<vector>
// the concept of a type wrapper
template<class T> struct type_wrapper;
// a model of type_wrapper for floats
template<>
struct type_wrapper<float> {
using type = float;
constexpr const char* name() const { return "Float"; }
};
// a model of type_wrapper for doubles
template<>
struct type_wrapper<double> {
using type = double;
constexpr const char* name() const { return "Double"; }
};
// call a template function once for each type wrapper in Ts...
template<class...Ts, class F>
auto for_each_type(F&& f)
{
(f(type_wrapper<Ts>()),...);
}
template<class T>
struct Matrix
{
Matrix(int, int);
T& operator()(int, int);
};
template<class T> Matrix<T> Problem2(int);
int main()
{
auto process = [](auto twrap) {
using T = typename decltype(twrap)::type;
std::ofstream writeDat;
std::vector<int> nValues = {26,51,101,201};
for(int i = 0; i< 4; i++){
int N = nValues[i];
Matrix<T> a(N,N);
Matrix<T> b(N,3);
Matrix<T> x = Problem2<T>(N);
std::string sFloat = "2/" + std::to_string(N) + twrap.name() + ".dat";
writeDat.open(sFloat);
for(int i =1; i<N ; i++)
writeDat << i << " " << x(i,1)<<std::endl;
writeDat << N <<" "<< x(N,1)<< std::endl;
writeDat.close();
}
};
for_each_type<double, float>(process);
}注意:
你可以像这样让for_each_type变得更便携(即在c++14上工作):
template<class...Ts, class F>
auto for_each_type(F&& f)
{
#if __cplusplus >= 201703L
(f(type_wrapper<Ts>()),...);
#else
using expand = int[];
expand {
0,
(f(type_wrapper<Ts>()), 0)...
};
#endif
}发布于 2018-09-24 15:38:53
我读过关于可变模板的文章,但我不明白如何在这种情况下应用它:
我相信@RichardHodges已经很好地回答了你的问题。作为参考,如果您希望能够将使用 (因为C++11)或 (因为C++17)的方式与仅使用的方式进行比较(并不是说这样做有特殊的原因),那么您可以使用下面的代码片段:
#include <vector>
#include <fstream>
using namespace std;
// Undefined struct
template <typename T> struct not_available;
// Non-specialized instantiations are not allowed, by using the undefined struct
template <typename T>
constexpr const char* type_string(){ return not_available<T>{}; }
// Specializing for `float`
template <>
constexpr const char* type_string<float>(){ return "Float"; }
// Specializing for `Double`
template <>
constexpr const char* type_string<double>(){ return "Double"; }
// Your classes
template<class T>
struct Matrix
{
Matrix(int, int);
T& operator()(int, int);
};
template<class T> Matrix<T> Problem2(int);
ofstream writeDat;
vector<int> nValues = {26,51,101,201};
// Your routine
template <typename T>
void func()
{
for(int i = 0; i< 4; i++){
int N = nValues[i];
Matrix<T> a(N,N);
Matrix<T> b(N,3);
Matrix<T> x = Problem2<T>(N);
string s = "2/" + to_string(N) + type_string<T>() +".dat";
writeDat.open(s);
for(int i =1; i<N ; i++)
writeDat << i << " " << x(i,1)<<endl;
writeDat << N <<" "<< x(N,1)<< endl;
writeDat.close();
}
}
int main(int argc, char* argv[])
{
func<float>();
func<double>();
return 0;
}注意:这段代码试图尽可能多地使用原始代码,但由于缺乏足够好的理由,我不建议使用全局变量,也不建议使用opting for using namespace std而不是使用std::引用名称。
https://stackoverflow.com/questions/52473354
复制相似问题