前瞻宣言&函子

时间:2012-01-12 16:39:22

标签: c++ forward-declaration

// backgammon.h

#ifndef BACKGAMMON_H
#define BACKGAMMON_H

#include <ctime>
#include <boost/random/mersenne_twister.hpp>
#include <boost/random/uniform_int_distribution.hpp>

namespace Backgammon
{

typedef boost::mt19937 Generator;
typedef boost::random::uniform_int_distribution<> Distribution;

template<typename Seed, typename Dist>
class roll_six {
  public:
    roll_six(Seed seed) : _seed(seed) {}
    int operator()() { 
      Dist dist(1, 6);
      return dist(_seed);
    }
  private:
    Seed _seed;
};

Generator gen(std::time(0));
roll_six<Generator,Distribution> roll_die(gen);

}

#endif

// backgammon.cpp

namespace Backgammon
{

// INSERT FORWARD DECLARATION FOR DICE FUNCTOR

}

roll_six类将六面模具模拟为仿函数。当我尝试为operator()()执行前向声明时,会出现问题。我知道对于backgammon.h,我必须使用分号来切断函数以显示它是原型,但是在backgammon.cpp中实现的正确语法是什么?

如果重要的话,这里是main.cpp:

// main.cpp
#include <iostream>
#include "backgammon.h"

int main(int argc, char** argv)
{
  std::cout << "Lets Play Backgammon" << std::endl;
  int roll = Backgammon::roll_die();
  std::cout << roll << std::endl;

  return 0;
}

4 个答案:

答案 0 :(得分:1)

我不确定我的问题是否正确,但你的意思是:

template <typename Seed, typename Dist>
int roll_six<Seed,Dist>::operator()() { 
  Dist dist(1, 6);
  return dist(_seed);
}

像往常一样,通过显式添加类名称(RollSix)来定义成员,对于模板类,您必须提供完整的模板参数来消除最终特化的歧义。

请注意,这只会定义 operator(),而不会实例化它。如果未在源文件中添加显式实例化,则不会实例化运算符,也不会在链接时提供运算符。您可以使用以下命令在cpp文件中显式实例化它:

template int roll_six<Generator,Distribution>::operator()();

答案 1 :(得分:0)

如果我理解你的话,不完全确定,但是

Generator gen(std::time(0));
roll_six<Generator,Distribution> roll_die(gen);

应该进入 backgammon.cpp

并在 backgammon.h 中需要

extern Generator gen;
extern roll_six<Generator,Distribution> roll_die;

答案 2 :(得分:0)

正确的语法就像定义其他成员函数一样,只是这个函数被称为operator()

template<typename Seed, typename Dist>
int RollSix<Seed, Dist>::operator()() 
{
    // whatever it does
}

但复杂的是,这是一个模板,因此无论在何处使用运算符,它都必须是可见的。因此,将它放在.cpp文件中是行不通的。它应该在标题中。

答案 3 :(得分:0)

解决方案!谢谢你们的贡献者。

//backgammon.h

#ifndef BACKGAMMON_H
#define BACKGAMMON_H

#include <ctime>
#include <boost/random/mersenne_twister.hpp>
#include <boost/random/uniform_int_distribution.hpp>

namespace Backgammon
{

typedef boost::mt19937 Generator;
typedef boost::random::uniform_int_distribution<> Distribution;

template<typename Seed, typename Dist>
class roll_six {
  public:
    roll_six(Seed seed) : _seed(seed) {}
    int operator()();
  private:
    Seed _seed;
};

/* no need to stick it in the .h file
template <typename Seed, typename Dist>
int roll_six<Seed,Dist>::operator()() { 
  Dist dist(1, 6);
  return dist(_seed);
}
*/

extern Generator gen;
extern roll_six<Generator,Distribution> roll_die;

}

#endif

// backgammon.cpp

#include "backgammon.h"

namespace Backgammon
{

Generator gen(std::time(0));
roll_six<Generator,Distribution> roll_die(gen);

template <typename Seed, typename Dist>
int roll_six<Seed,Dist>::operator()() { 
  Dist dist(1, 6);
  return dist(_seed);
}

template int roll_six<Generator,Distribution>::operator()();

}

// makefile

all:
    g++ -o .o main.cpp backgammon.cpp
    ./.o