将使用包含的程序转换为使用模板的程序

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;
}