我正在撰写一个程序,其中包含list<T>
,其中T
为int
或double
。我想创建一个函数,使用标题<random>
中的组件生成T
类型的数字。我找不到以T
作为模板参数的分发。
然后该函数将用于调用generate
函数:
generate(myList.begin(), myList.end(), RandomGenerator())
我该怎么做?
我尝试创建一个名为RandomGenerator
的类,并为其重载operator()
。
当我尝试将参数传递给重载的operator()
时,我得到一个错误。
函数调用,Random(b)
是一个带有int
参数b
的函数对象:
generate(rList.begin(), rList.end(), Random(b));
重载代码()
,其中n
是一种“虚拟”变量,只是告诉它是什么类型:
int operator()(int n)
{
std::uniform_int_distribution<int> dist(1000, 2000);
return dist(gen);
}
错误讯息:
Error 2 error C2440: '<function-style-cast>' : cannot convert from 'int' to 'Random'
Error 3 error C2780: 'void std::generate(_FwdIt,_FwdIt,_Fn0)' : expects 3 arguments - 2 provided
答案 0 :(得分:3)
不是一个优雅的解决方案,但你做了你想要的:(修改代码,以便它可以与生成一起使用)
template <typename Distribution>
class RandomGenerator
{
using Type = typename Distribution::result_type;
const Type getRandom(const Type& lower, const Type& upper) const
{
static std::default_random_engine generator;
static Distribution distribution(lower, upper);
return distribution(generator);
}
public:
RandomGenerator(const Type& lowerBound, const Type& upperBound) : _lowerBound(lowerBound), _upperBound(upperBound) { }
const Type operator()() const
{
return getRandom(_lowerBound, _upperBound);
}
private:
Type _lowerBound;
Type _upperBound;
};
int main()
{
RandomGenerator<std::uniform_int_distribution<>> randomIntGenerator(1, 10);
RandomGenerator<std::uniform_real_distribution<>> randomDoubleGenerator(0.0, 10.0);
std::deque<int> intRandoms(10);
std::generate(intRandoms.begin(), intRandoms.end(), randomIntGenerator);
std::deque<double> doubleRandoms(5);
std::generate(doubleRandoms.begin(), doubleRandoms.end(), randomDoubleGenerator);
return 0;
}
当然,如果我们想要每次运行都有不同的数字,我们可以将default_random_engine的种子设置为类似于时间(0)的东西,但是我会把它留下来。
答案 1 :(得分:3)
除了Joey的回答,以下内容应与std::generate
很好地配合使用。免责声明:我在元编程方面很糟糕,请指出任何错误或可能的改进。这是一个C ++ 11解决方案,使用C ++ 14会有点短。
#include <algorithm>
#include <iostream>
#include <list>
#include <random>
#include <type_traits>
template<typename T,
typename = typename std::enable_if<std::is_arithmetic<T>::value>::type>
class random_generator {
using distribution_type = typename std::conditional<
std::is_integral<T>::value,
std::uniform_int_distribution<T>,
std::uniform_real_distribution<T>
>::type;
std::default_random_engine engine;
distribution_type distribution;
public:
auto operator()() -> decltype(distribution(engine)) {
return distribution(engine);
}
};
template<typename Container, typename T = typename Container::value_type>
auto make_generator(Container const&) -> decltype(random_generator<T>()) {
return random_generator<T>();
}
int main() {
auto l = std::list<double>(10);
std::generate(std::begin(l), std::end(l), make_generator(l));
for (auto i : l) {
std::cout << i << " ";
}
}