我正在研究一个到学校的项目(因为命名空间名称可能提示,它是2D游戏)并且我创建了一个名为RangeInt(Range)的自定义类,它只包含两个相同类型的变量,并创建另一个名为Randomizer的类,它包装了生成C ++ 11标准随机数,并使用RangeInt类指定我想要生成数字的范围。
不管怎样,这里是代码:
namespace game{
template<class _Type>
//very simple class representing virtual Range
//of type _Type(template argument) and storing
//upper and lower bound
class Range{
public:
typedef _Type TemplateParam;
//value sto use of type _Type
_Type first, second;
//copy constructor:
Range(const Range& rng)
{
first = rng.first;
second = rng.second;
}
//move construct:
Range(Range&& rng)
{
std::swap(*this, rng);
}
Range& operator=(const Range& range)
{
first = range.first;
second = range.second;
return *this;
}
Range& operator=(Range&& range)
{
std::swap(first, range.first);
std::swap(second, range.second);
return *this;
}
//constructor
Range(_Type one, _Type two) : first(one), second(two) {}
//returns two - one
inline _Type getDifference() { return two - one; }
};
typedef Range<uint> RangeInt;
};
和随机数发生器:
namespace game{
template <class _RNG = xorshift>
class Randomizer_RNG{
typedef _RNG random_generator;
RangeInt rng;
random_generator mt;
std::uniform_int_distribution<> dist;
//reinitialize the dist variable so it actually knows the new range
void _changeDist()
{
dist = std::uniform_int_distribution<>(rng.first, rng.second);
}
public:
//default constructor, set rng to maximum range and initialize
//the xorshift with seed being current time and specify the
//range for uniform_int_distribution
Randomizer_RNG()
{
rng = game::RangeInt(0, std::numeric_limits<game::uint>::max());
dist = std::uniform_int_distribution<>(range.first, range.second);
mt.seed(std::chrono::high_resolution_clock::now().time_since_epoch().count());
}
//do the same as constructor above but with specified range
explicit Randomizer_RNG(RangeInt range) : rng(range)
{
dist = std::uniform_int_distribution<>(rng.first, rng.second);
mt.seed(std::chrono::high_resolution_clock::now().time_since_epoch().count());
}
//copy constructor
Randomizer_RNG(const Randomizer_RNG& lhs)
{
dist = lhs.dist;
mt = lhs.mt;
rng = lhs.rng;
}
//move constructor
Randomizer_RNG(Randomizer_RNG&& lhs)
{
std::swap(*this, lhs);
}
//reseed with current time
inline void seed()
{
mt.seed(std::chrono::high_resolution_clock::now().time_since_epoch().count());
}
//reseed with specified value
inline void seed(unsigned long long newSeed)
{
mt.seed(newSeed);
}
//default operator()
uint32 operator()()
{
return dist(mt);
}
//return value generated in range of
//<fitWithin.first, fitWithin.second>
uint32 operator()(RangeInt&& fitWithin)
{
decltype(dist) l_dist(fitWithin.first, fitWithin.second);
return l_dist(mt);
}
//the same as above, but with rvalue reference
uint32 operator()(RangeInt& fitWithin)
{
decltype(dist) l_dist(fitWithin.first, fitWithin.second);
return l_dist(mt);
}
//change range with reference
void changeRange(const RangeInt& rng)
{
this->rng = rng;
_changeDist();
}
//the same as above but with rvalue reference
void changeRange(RangeInt&& rng)
{
std::swap(this->rng, rng);
_changeDist();
}
//set the upper bound of the range and update rng
void setUpperBound(RangeInt::TemplateParam upBound)
{
rng.second = upBound;
_changeDist();
}
//set the lower bound of the range and update rng
void setLowerBound(RangeInt::TemplateParam lowBound)
{
rng.first = lowBound;
_changeDist();
}
//copy assignment
Randomizer_RNG& operator=(const Randomizer_RNG& lhs)
{
_RETURN_IF_THIS(lhs, *this); //if (*this == lhs) return *this;
rng = lhs.rng;
changeRange(rng);
return *this;
}
//move assignment
Randomizer_RNG& operator=(Randomizer_RNG&& lhs)
{
dist = std::move(lhs.dist);
rng = std::move(lhs.rng);
mt = std::move(lhs.mt);
return *this;
}
};
typedef Randomizer_RNG<> Randomizer;
typedef Randomizer_RNG<std::mt19937> Randomizer_Twist;
};
但是当我做的时候
#include "randomizer.h"
int main()
{
game::RangeInt rngI (14, 546);
game::Randomizer rng = game::Randomizer(game::RangeInt(0, 100));
auto func = std::bind(rng, rngI);
std::cout << func();
std::cin.get();
}
它弹出编译器错误:
error C2512: 'game::Range<_Type>' : no appropriate default constructor available
with
[
_Type=game::uint
]
如果我尝试这样做:
#include "randomizer.h"
int main()
{
game::RangeInt rngI (14, 546);
game::Randomizer rng = game::Randomizer(game::RangeInt(0, 100));
auto func = std::bind(&rng, rngI);
std::cout << func();
std::cin.get();
}
它说:
错误C2679:二进制&#39;&lt;&lt;&# :没有找到哪个运算符采用类型&#39; std :: _ Do_call_ret&lt; _Forced,_Ret,_Funx,_Btuple,_Ftuple&gt; :: type&#39;的右手操作数(或者没有可接受的转换)
所以我想知道我做错了什么或为什么std :: bind想要来自我的默认构造函数game :: Range。
如果我的问题不明确或代码不清楚,请告诉我,我会尽力而为。
PS:我使用Visual Studio 2012,因此没有实现Variadic模板(例如std :: bind有378个重叠)
答案 0 :(得分:2)
成功
Randomizer_RNG(const Randomizer_RNG& lhs)
: dist(lhs.dist), mt(lhs.mt), rng(lhs.rng)
{}
或者完全删除这个构造函数:编译器生成的构造函数就足够了。
如上所述,构造函数首先尝试默认构造rng
,然后分配给它。但是,正如编译器告诉您的那样,Range
不提供默认构造函数。