将使用包含的程序转换为使用模板的程序
Convert a program that uses includes to one using templates
我已经创建了一个示例来展示我正在使用的语言功能,实际情况并不那么简单。包含文件被包含两次,每个 class 一次。尽管文本相同,但底层类型不同。在实际情况下,根据 class.
,某些变量比其他变量具有更多的初始化
工作计划
ex1.cpp
#include <iostream>
class one {
public:
one(int a1,int b1) : a(a1), b(b1) {}
int a,b;
#include "ex1.h"
};
class two {
public:
two(double a1,double b1) : a(a1), b(b1) {}
double a,b;
#include "ex1.h"
};
int main()
{
one c1(1,2);
two c2(3.4,5.7);
c1.f();
c2.f();
return 0;
}
ex1.h
void f()
{
std::cout << ( a + b ) << std::endl;
}
我希望将其更改为如下使用模板的程序,但出现编译错误。
ex2.cpp
#include <iostream>
class one {
public:
one(int a1,int b1) : a(a1), b(b1) {}
int a,b;
void f();
};
class two {
public:
two(double a1,double b1) : a(a1), b(b1) {}
double a,b;
void f();
};
template<typename X>
void X::f()
{
std::cout << ( a + b ) << std::endl;
}
int main()
{
one c1(1,2);
two c2(3.4,5.7);
c1.f();
c2.f();
return 0;
}
报错信息为error: invalid use of template type parameter'X'
我相信做你想做的事情的正确方法是使用模板来处理 class 中存在的不同类型:
#include <iostream>
template<typename X>
class foo {
public:
foo(X a1, X b1) : a(a1), b(b1) {}
X a,b;
void f();
};
template<typename X>
void foo<X>::f()
{
std::cout << ( a + b ) << std::endl;
}
int main()
{
foo<int> c1(1,2);
foo<double> c2(3.4,5.7);
c1.f();
c2.f();
return 0;
}
一般来说,您不希望 #include
代码直接进入您的 class 以消除代码重复,c++ 为您提供了一些更好的选择。
您可以在此处查看 运行:http://coliru.stacked-crooked.com/a/34d146d7feac8abd
CRTP 救援:
template<class D>
struct f_support {
void f() {
// does not block all errors, but catches some:
static_assert( std::is_base_of< f_support, D >::value, "CRTP failure" );
auto* dis = static_cast<D*>(this);
std::cout << ( dis->a + dis->b ) << std::endl;
}
};
然后:
class one: public f_support<one> {
...
class two: public f_support<two> {
...
您可以将 f_support<D>
的实现移动到 .cpp 文件中,但这很麻烦。
感谢@Yakk 和@shuttle87 的回答。我利用了 shuttle87 的简单回答和 Yakk 的灵活回答来提出这个问题。没有你的帮助,我仍然会使用包含文件。 我下面的解决方案的问题是它要求所有 类 在其构造函数中具有相同数量的参数。
#include <iostream>
class one {
public:
one(int a1,int b1) : a(a1), b(b1) {}
int a,b;
void g() { std::cout << "one\t"; }
};
class two {
public:
two(double a1,double b1) : a(a1), b(b1) {}
double a,b;
void g() { std::cout << "two\t"; }
};
template<class X, typename Y>
class three : public X {
public:
three(Y a, Y b) : X(a,b) {}
void f()
{
X::g();
std::cout << ( X::a + X::b ) << std::endl;
}
};
int main()
{
three<one,int> c1(1,2);
three<two,double> c2(3.4,5.7);
c1.f();
c2.f();
return 0;
}
我已经创建了一个示例来展示我正在使用的语言功能,实际情况并不那么简单。包含文件被包含两次,每个 class 一次。尽管文本相同,但底层类型不同。在实际情况下,根据 class.
,某些变量比其他变量具有更多的初始化工作计划
ex1.cpp
#include <iostream>
class one {
public:
one(int a1,int b1) : a(a1), b(b1) {}
int a,b;
#include "ex1.h"
};
class two {
public:
two(double a1,double b1) : a(a1), b(b1) {}
double a,b;
#include "ex1.h"
};
int main()
{
one c1(1,2);
two c2(3.4,5.7);
c1.f();
c2.f();
return 0;
}
ex1.h
void f()
{
std::cout << ( a + b ) << std::endl;
}
我希望将其更改为如下使用模板的程序,但出现编译错误。
ex2.cpp
#include <iostream>
class one {
public:
one(int a1,int b1) : a(a1), b(b1) {}
int a,b;
void f();
};
class two {
public:
two(double a1,double b1) : a(a1), b(b1) {}
double a,b;
void f();
};
template<typename X>
void X::f()
{
std::cout << ( a + b ) << std::endl;
}
int main()
{
one c1(1,2);
two c2(3.4,5.7);
c1.f();
c2.f();
return 0;
}
报错信息为error: invalid use of template type parameter'X'
我相信做你想做的事情的正确方法是使用模板来处理 class 中存在的不同类型:
#include <iostream>
template<typename X>
class foo {
public:
foo(X a1, X b1) : a(a1), b(b1) {}
X a,b;
void f();
};
template<typename X>
void foo<X>::f()
{
std::cout << ( a + b ) << std::endl;
}
int main()
{
foo<int> c1(1,2);
foo<double> c2(3.4,5.7);
c1.f();
c2.f();
return 0;
}
一般来说,您不希望 #include
代码直接进入您的 class 以消除代码重复,c++ 为您提供了一些更好的选择。
您可以在此处查看 运行:http://coliru.stacked-crooked.com/a/34d146d7feac8abd
CRTP 救援:
template<class D>
struct f_support {
void f() {
// does not block all errors, but catches some:
static_assert( std::is_base_of< f_support, D >::value, "CRTP failure" );
auto* dis = static_cast<D*>(this);
std::cout << ( dis->a + dis->b ) << std::endl;
}
};
然后:
class one: public f_support<one> {
...
class two: public f_support<two> {
...
您可以将 f_support<D>
的实现移动到 .cpp 文件中,但这很麻烦。
感谢@Yakk 和@shuttle87 的回答。我利用了 shuttle87 的简单回答和 Yakk 的灵活回答来提出这个问题。没有你的帮助,我仍然会使用包含文件。 我下面的解决方案的问题是它要求所有 类 在其构造函数中具有相同数量的参数。
#include <iostream>
class one {
public:
one(int a1,int b1) : a(a1), b(b1) {}
int a,b;
void g() { std::cout << "one\t"; }
};
class two {
public:
two(double a1,double b1) : a(a1), b(b1) {}
double a,b;
void g() { std::cout << "two\t"; }
};
template<class X, typename Y>
class three : public X {
public:
three(Y a, Y b) : X(a,b) {}
void f()
{
X::g();
std::cout << ( X::a + X::b ) << std::endl;
}
};
int main()
{
three<one,int> c1(1,2);
three<two,double> c2(3.4,5.7);
c1.f();
c2.f();
return 0;
}