在 class 接口内的模板化静态方法中使用 std::generator_canonical
Working with std::generator_canonical in a templated static method within a class interface
我正在开发 class 不实例化实例;它有一个受保护的构造函数,所有方法都是静态的。这个 class 我简化了对 <random>
中发现的各种随机引擎的调用 我有一个类似的 class 对不同的分布类型做同样的事情。我对我的引擎的所有静态调用都可以正常工作,并且能够以多种方式对它们进行播种。我现在正在开发我的同伴 class 来处理不同的发行版。到目前为止,我已经能够完成 std::uniform_int
、std::uniform_int_distribution
、std::uniform_real
和 std::uniform_real_distribution
并取得圆满成功。现在我已经开始使用 std::generate_canonical
我开始遇到编译器错误。
这是我的 RandomGenerator 头文件的样子:
#ifndef RANDOM_GENERATOR_H
#define RANDOM_GENERATOR_H
#include <chrono>
#include <random>
class RandomEngine {
public:
using Clock = std::conditional_t<std::chrono::high_resolution_clock::is_steady,
std::chrono::high_resolution_clock,
std::chrono::steady_clock>;
// Used To Determine Which Seeding Process To Use
enum SeedType {
USE_CHRONO_CLOCK,
USE_RANDOM_DEVICE,
USE_SEED_VALUE,
USE_SEED_SEQ,
}; // SeedType
// This Enum Is Not In Use - It Is A Visual Reference Only; But If User Wants To
// Use It For Their Own Pupose They Are Free To Do So.
enum EngineType {
// Default Random Engine
DEFAULT_RANDOM_ENGINE,
// Linear Congruential Engines
MINSTD_RAND0,
MINSTD_RAND,
// Mersenne Twister Engines
MT19937,
MT19937_64,
// Subtract With Carry Engines
RANLUX24_BASE,
RANLUX48_BASE,
// Discard Block Engines
RANLUX24,
RANLUX48,
// Shuffle Order Engines
KNUTH_B,
}; // EngineType
protected:
RandomEngine(){}
public:
static unsigned int getTimeNow() {
unsigned int now = static_cast<unsigned int>(Clock::now().time_since_epoch().count());
return now;
} // getTimeNow
static std::random_device& getRandomDevice() {
static std::random_device device{};
return device;
} // getRandomDevice
static std::default_random_engine& getDefaultRandom( SeedType type, unsigned seedValue = 0, std::seed_seq& seq = std::seed_seq{} ) {
static std::default_random_engine engine{};
if ( type == USE_RANDOM_DEVICE ) {
engine.seed( getRandomDevice()() );
}
if ( type == USE_CHRONO_CLOCK ) {
engine.seed( getTimeNow() );
}
if ( type == USE_SEED_VALUE ) {
engine.seed( seedValue );
}
if ( type == USE_SEED_SEQ ) {
engine.seed( seq );
}
return engine;
} // getDefaultEngine
static std::minstd_rand0& getMinStd_Rand0( SeedType type, unsigned seedValue = 0 ) {
static std::minstd_rand0 engine{};
if ( type == USE_RANDOM_DEVICE ) {
engine.seed( getRandomDevice()() );
}
if ( type == USE_CHRONO_CLOCK ) {
engine.seed( getTimeNow() );
}
if ( type == USE_SEED_VALUE ) {
engine.seed( seedValue );
}
return engine;
} // getMinStd_Rand0
static std::minstd_rand& getMinStd_Rand( SeedType type, unsigned seedValue = 0 ) {
static std::minstd_rand engine{};
if ( type == USE_RANDOM_DEVICE ) {
engine.seed( getRandomDevice()() );
}
if ( type == USE_CHRONO_CLOCK ) {
engine.seed( getTimeNow() );
}
if ( type == USE_SEED_VALUE ) {
engine.seed( seedValue );
}
return engine;
} // getMinStd_Rand
static std::mt19937& getMt19937( SeedType type, unsigned seedValue = 0 ) {
static std::mt19937 engine{};
if ( type == USE_RANDOM_DEVICE ) {
engine.seed( getRandomDevice()() );
}
if ( type == USE_CHRONO_CLOCK ) {
engine.seed( getTimeNow() );
}
if (type == USE_SEED_VALUE) {
engine.seed( seedValue );
}
return engine;
} //getMt19937
static std::mt19937_64& getMt19937_64( SeedType type, unsigned seedValue = 0 ) {
static std::mt19937_64 engine{};
if (type == USE_RANDOM_DEVICE) {
engine.seed(getRandomDevice()());
}
if (type == USE_CHRONO_CLOCK) {
engine.seed(getTimeNow());
}
if (type == USE_SEED_VALUE) {
engine.seed(seedValue);
}
return engine;
} // getMt19937_64
static std::ranlux24_base& getRanLux24_base( SeedType type, unsigned seedValue = 0 ) {
static std::ranlux24_base engine{};
if ( type == USE_RANDOM_DEVICE ) {
engine.seed( getRandomDevice()() );
}
if ( type == USE_CHRONO_CLOCK ) {
engine.seed( getTimeNow() );
}
if ( type == USE_SEED_VALUE ) {
engine.seed( seedValue );
}
return engine;
} // getRanLux24_base
static std::ranlux48_base& getRanLux48_base( SeedType type, unsigned seedValue = 0 ) {
static std::ranlux48_base engine{};
if ( type == USE_RANDOM_DEVICE ) {
engine.seed( getRandomDevice()() );
}
if ( type == USE_CHRONO_CLOCK ) {
engine.seed( getTimeNow() );
}
if ( type == USE_SEED_VALUE ) {
engine.seed( seedValue );
}
return engine;
} // getRanLux48_base
static std::ranlux24& getRanLux24( SeedType type, unsigned seedValue = 0 ) {
static std::ranlux24 engine{};
if ( type == USE_RANDOM_DEVICE ) {
engine.seed( getRandomDevice()() );
}
if ( type == USE_CHRONO_CLOCK ) {
engine.seed( getTimeNow() );
}
if ( type == USE_SEED_VALUE ) {
engine.seed( seedValue );
}
return engine;
} // getRanLux24
static std::ranlux48& getRanLux48( SeedType type, unsigned seedValue = 0 ) {
static std::ranlux48 engine{};
if ( type == USE_RANDOM_DEVICE ) {
engine.seed( getRandomDevice()() );
}
if ( type == USE_CHRONO_CLOCK ) {
engine.seed( getTimeNow() );
}
if ( type == USE_SEED_VALUE ) {
engine.seed( seedValue );
}
return engine;
} //getRanLux48
}; // RandomEngine
class RandomDistribution {
public:
// This Enum Is Not In Use - It Is A Visual Reference Only; But If User Wants To
// Use It For Their Own Pupose They Are Free To Do So.
enum DistributionType {
// Uniform Distributions
UNIFORM_INT,
UNIFORM_INT_DISTRIBUTION,
UNIFORM_REAL,
UNIFORM_REAL_DISTRIBUTION,
GENERATE_CANONICAL,
// Bernoulli Distributions
BERNOULLI_DISTRIBUTION,
BINOMAIL_DISTRIBUTION,
NEGATIVE_BINOMIAL_DISTRIBUTION,
GEOMETRIC_DISTRIBUTION,
// Poisson Distributions
POISSON_DISTRIBUTION,
EXPONENTIAL_DISTRIBUTION,
GAMMA_DISTRIBUTION,
WEIBULL_DISTRIBUTION,
EXTREME_VALUE_DISTRIBUTION,
// Normal Distributions
NORMAL_DISTRIBUTION,
LOGNORMAL_DISTRIBUTION,
CHI_SQUARED_DISTRIBUTION,
CAUCHY_DISTRIBUTION,
FISHER_F_DISTRIBUTION,
STUDENT_T_DISTRIBUTION,
// Sampling Distributions
DISCRETE_DISTRIBUTION,
PIECEWISE_CONSTANT_DISTRIBUTION,
PIECEWISE_LINEAR_DISTRIBUTION
}; // DistributionType
protected:
RandomDistribution(){}
public:
template<class IntType = int>
static std::uniform_int<IntType>& getUniformInt( IntType lowerBound, IntType upperBound ) {
static std::uniform_int<IntType> dist( lowerBound, upperBound );
return dist;
} // getUniformInt
template<class IntType = int>
static std::uniform_int<IntType>& getUniformIntDistribution( IntType lowerBound, IntType upperBound ) {
static std::uniform_int_distribution<IntType> dist( lowerBound, upperBound );
return dist;
} // getUniformIntDistribution
template<class RealType = double>
static std::uniform_real<RealType>& getUniformReal( RealType lowerBound, RealType upperBound ) {
static std::uniform_real<RealType> dist( lowerBound, uppperBound );
return dist;
} // getUniformReal
template<class RealType = double>
static std::uniform_real_distribution<RealType>& getUniformRealDistribution( RealType lowerBound, RealType upperBound ) {
static std::uniform_real_distribution<RealType> dist( lowerBound, upperBound );
return dist;
} // getUniformRealDistribution
template<class RealType = double, std::size_t numBits, class Generator>
static std::generate_canonical<RealType, numBits>& getGenerateCanonical( Generator& engine ) {
static std::generate_canonical<RealType, numBits> dist( engine );
return dist;
} // getGeneratorCanonical
}; // RandomDistribution
typedef RandomEngine RE;
typedef RandomDistribution RD;
// #include "RandomGeneator.inl"
#endif // RANDOM_GENERATOR_H
我正在开发的就是这个功能
template<class RealType = double, std::size_t numBits, class Generator>
static std::generate_canonical<RealType, numBits>& getGenerateCanonical( Generator& engine ) {
static std::generate_canonical<RealType, numBits> dist( engine );
return dist;
} // getGeneratorCanonical
我一直遵循这个网站的语法:cppreference 他们有这行代码
std::cout << std::generate_canonical<double, 10>(gen) << ' ';
我正在尝试创建并 return 此发行版的静态实例。模板参数中的 RealType 默认为 double,最好与 std::generate_canonical
一起使用,std::size_t 是第二个模板参数字段中的位数,第三个模板参数表示 RandomEngine 生成器传递给它。 Howe 我无法正确定义此功能。我不断收到来自 VS2015
的编译器错误
1>------ Build started: Project: DieRoll, Configuration: Debug Win32 ------
1> RandomGenerator.cpp
1>c:\users\skilz80\documents\visual studio 2015\projects\dieroll\dieroll\randomgenerator.h(297): error C2988: unrecognizable template declaration/definition
1>c:\users\skilz80\documents\visual studio 2015\projects\dieroll\dieroll\randomgenerator.h(297): error C2143: syntax error: missing ';' before '&'
1>c:\users\skilz80\documents\visual studio 2015\projects\dieroll\dieroll\randomgenerator.h(297): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
1>c:\users\skilz80\documents\visual studio 2015\projects\dieroll\dieroll\randomgenerator.h(297): error C2365: 'std::generate_canonical': redefinition; previous definition was 'function'
1> c:\program files (x86)\microsoft visual studio 14.0\vc\include\random(295): note: see declaration of 'std::generate_canonical'
1>c:\users\skilz80\documents\visual studio 2015\projects\dieroll\dieroll\randomgenerator.h(297): error C2238: unexpected token(s) preceding ';'
1>c:\users\skilz80\documents\visual studio 2015\projects\dieroll\dieroll\randomgenerator.h(297): error C2059: syntax error: '&'
1>c:\users\skilz80\documents\visual studio 2015\projects\dieroll\dieroll\randomgenerator.h(304): error C2143: syntax error: missing ';' before '}'
1>c:\users\skilz80\documents\visual studio 2015\projects\dieroll\dieroll\randomgenerator.h(304): error C2238: unexpected token(s) preceding ';'
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========
我试过其他方法来定义它,但我得到了非常相似的错误。我不需要这些功能来完成实际工作,因为它留给了用户定义,我只是创建一个简单的用户界面,以便快速轻松地创建一个准备好的 RandomEngine 和一个 PreparedDistribution,其中静态生成一个实例,但是用户仍然可以选择创建正在使用的类型的局部变量。任何有关如何正确构造此静态函数的建议都将受到赞赏。
编辑 感谢 ildjarn 提到 std::generate_canonical 是一个函数而不是 class 模板。当我回到我所引用的网站时,他们确实以小绿色文本将其列为函数模板,而不是 class 模板。既然我直接知道它是什么,我就可以从我的 class 中省略它而不用担心它。现在,这消除了我在无法编译时遇到的一些困惑。
编辑
我终于完成了我的 class 并合并了所有主要发行版并测试了它们,它们似乎都可以正常工作。我还删除了 std::uniform_int
和 std::uniform_real
,因为它们只是各自分布的基础 classes。
std::generate_canonical
是函数,不是类型。
我正在开发 class 不实例化实例;它有一个受保护的构造函数,所有方法都是静态的。这个 class 我简化了对 <random>
中发现的各种随机引擎的调用 我有一个类似的 class 对不同的分布类型做同样的事情。我对我的引擎的所有静态调用都可以正常工作,并且能够以多种方式对它们进行播种。我现在正在开发我的同伴 class 来处理不同的发行版。到目前为止,我已经能够完成 std::uniform_int
、std::uniform_int_distribution
、std::uniform_real
和 std::uniform_real_distribution
并取得圆满成功。现在我已经开始使用 std::generate_canonical
我开始遇到编译器错误。
这是我的 RandomGenerator 头文件的样子:
#ifndef RANDOM_GENERATOR_H
#define RANDOM_GENERATOR_H
#include <chrono>
#include <random>
class RandomEngine {
public:
using Clock = std::conditional_t<std::chrono::high_resolution_clock::is_steady,
std::chrono::high_resolution_clock,
std::chrono::steady_clock>;
// Used To Determine Which Seeding Process To Use
enum SeedType {
USE_CHRONO_CLOCK,
USE_RANDOM_DEVICE,
USE_SEED_VALUE,
USE_SEED_SEQ,
}; // SeedType
// This Enum Is Not In Use - It Is A Visual Reference Only; But If User Wants To
// Use It For Their Own Pupose They Are Free To Do So.
enum EngineType {
// Default Random Engine
DEFAULT_RANDOM_ENGINE,
// Linear Congruential Engines
MINSTD_RAND0,
MINSTD_RAND,
// Mersenne Twister Engines
MT19937,
MT19937_64,
// Subtract With Carry Engines
RANLUX24_BASE,
RANLUX48_BASE,
// Discard Block Engines
RANLUX24,
RANLUX48,
// Shuffle Order Engines
KNUTH_B,
}; // EngineType
protected:
RandomEngine(){}
public:
static unsigned int getTimeNow() {
unsigned int now = static_cast<unsigned int>(Clock::now().time_since_epoch().count());
return now;
} // getTimeNow
static std::random_device& getRandomDevice() {
static std::random_device device{};
return device;
} // getRandomDevice
static std::default_random_engine& getDefaultRandom( SeedType type, unsigned seedValue = 0, std::seed_seq& seq = std::seed_seq{} ) {
static std::default_random_engine engine{};
if ( type == USE_RANDOM_DEVICE ) {
engine.seed( getRandomDevice()() );
}
if ( type == USE_CHRONO_CLOCK ) {
engine.seed( getTimeNow() );
}
if ( type == USE_SEED_VALUE ) {
engine.seed( seedValue );
}
if ( type == USE_SEED_SEQ ) {
engine.seed( seq );
}
return engine;
} // getDefaultEngine
static std::minstd_rand0& getMinStd_Rand0( SeedType type, unsigned seedValue = 0 ) {
static std::minstd_rand0 engine{};
if ( type == USE_RANDOM_DEVICE ) {
engine.seed( getRandomDevice()() );
}
if ( type == USE_CHRONO_CLOCK ) {
engine.seed( getTimeNow() );
}
if ( type == USE_SEED_VALUE ) {
engine.seed( seedValue );
}
return engine;
} // getMinStd_Rand0
static std::minstd_rand& getMinStd_Rand( SeedType type, unsigned seedValue = 0 ) {
static std::minstd_rand engine{};
if ( type == USE_RANDOM_DEVICE ) {
engine.seed( getRandomDevice()() );
}
if ( type == USE_CHRONO_CLOCK ) {
engine.seed( getTimeNow() );
}
if ( type == USE_SEED_VALUE ) {
engine.seed( seedValue );
}
return engine;
} // getMinStd_Rand
static std::mt19937& getMt19937( SeedType type, unsigned seedValue = 0 ) {
static std::mt19937 engine{};
if ( type == USE_RANDOM_DEVICE ) {
engine.seed( getRandomDevice()() );
}
if ( type == USE_CHRONO_CLOCK ) {
engine.seed( getTimeNow() );
}
if (type == USE_SEED_VALUE) {
engine.seed( seedValue );
}
return engine;
} //getMt19937
static std::mt19937_64& getMt19937_64( SeedType type, unsigned seedValue = 0 ) {
static std::mt19937_64 engine{};
if (type == USE_RANDOM_DEVICE) {
engine.seed(getRandomDevice()());
}
if (type == USE_CHRONO_CLOCK) {
engine.seed(getTimeNow());
}
if (type == USE_SEED_VALUE) {
engine.seed(seedValue);
}
return engine;
} // getMt19937_64
static std::ranlux24_base& getRanLux24_base( SeedType type, unsigned seedValue = 0 ) {
static std::ranlux24_base engine{};
if ( type == USE_RANDOM_DEVICE ) {
engine.seed( getRandomDevice()() );
}
if ( type == USE_CHRONO_CLOCK ) {
engine.seed( getTimeNow() );
}
if ( type == USE_SEED_VALUE ) {
engine.seed( seedValue );
}
return engine;
} // getRanLux24_base
static std::ranlux48_base& getRanLux48_base( SeedType type, unsigned seedValue = 0 ) {
static std::ranlux48_base engine{};
if ( type == USE_RANDOM_DEVICE ) {
engine.seed( getRandomDevice()() );
}
if ( type == USE_CHRONO_CLOCK ) {
engine.seed( getTimeNow() );
}
if ( type == USE_SEED_VALUE ) {
engine.seed( seedValue );
}
return engine;
} // getRanLux48_base
static std::ranlux24& getRanLux24( SeedType type, unsigned seedValue = 0 ) {
static std::ranlux24 engine{};
if ( type == USE_RANDOM_DEVICE ) {
engine.seed( getRandomDevice()() );
}
if ( type == USE_CHRONO_CLOCK ) {
engine.seed( getTimeNow() );
}
if ( type == USE_SEED_VALUE ) {
engine.seed( seedValue );
}
return engine;
} // getRanLux24
static std::ranlux48& getRanLux48( SeedType type, unsigned seedValue = 0 ) {
static std::ranlux48 engine{};
if ( type == USE_RANDOM_DEVICE ) {
engine.seed( getRandomDevice()() );
}
if ( type == USE_CHRONO_CLOCK ) {
engine.seed( getTimeNow() );
}
if ( type == USE_SEED_VALUE ) {
engine.seed( seedValue );
}
return engine;
} //getRanLux48
}; // RandomEngine
class RandomDistribution {
public:
// This Enum Is Not In Use - It Is A Visual Reference Only; But If User Wants To
// Use It For Their Own Pupose They Are Free To Do So.
enum DistributionType {
// Uniform Distributions
UNIFORM_INT,
UNIFORM_INT_DISTRIBUTION,
UNIFORM_REAL,
UNIFORM_REAL_DISTRIBUTION,
GENERATE_CANONICAL,
// Bernoulli Distributions
BERNOULLI_DISTRIBUTION,
BINOMAIL_DISTRIBUTION,
NEGATIVE_BINOMIAL_DISTRIBUTION,
GEOMETRIC_DISTRIBUTION,
// Poisson Distributions
POISSON_DISTRIBUTION,
EXPONENTIAL_DISTRIBUTION,
GAMMA_DISTRIBUTION,
WEIBULL_DISTRIBUTION,
EXTREME_VALUE_DISTRIBUTION,
// Normal Distributions
NORMAL_DISTRIBUTION,
LOGNORMAL_DISTRIBUTION,
CHI_SQUARED_DISTRIBUTION,
CAUCHY_DISTRIBUTION,
FISHER_F_DISTRIBUTION,
STUDENT_T_DISTRIBUTION,
// Sampling Distributions
DISCRETE_DISTRIBUTION,
PIECEWISE_CONSTANT_DISTRIBUTION,
PIECEWISE_LINEAR_DISTRIBUTION
}; // DistributionType
protected:
RandomDistribution(){}
public:
template<class IntType = int>
static std::uniform_int<IntType>& getUniformInt( IntType lowerBound, IntType upperBound ) {
static std::uniform_int<IntType> dist( lowerBound, upperBound );
return dist;
} // getUniformInt
template<class IntType = int>
static std::uniform_int<IntType>& getUniformIntDistribution( IntType lowerBound, IntType upperBound ) {
static std::uniform_int_distribution<IntType> dist( lowerBound, upperBound );
return dist;
} // getUniformIntDistribution
template<class RealType = double>
static std::uniform_real<RealType>& getUniformReal( RealType lowerBound, RealType upperBound ) {
static std::uniform_real<RealType> dist( lowerBound, uppperBound );
return dist;
} // getUniformReal
template<class RealType = double>
static std::uniform_real_distribution<RealType>& getUniformRealDistribution( RealType lowerBound, RealType upperBound ) {
static std::uniform_real_distribution<RealType> dist( lowerBound, upperBound );
return dist;
} // getUniformRealDistribution
template<class RealType = double, std::size_t numBits, class Generator>
static std::generate_canonical<RealType, numBits>& getGenerateCanonical( Generator& engine ) {
static std::generate_canonical<RealType, numBits> dist( engine );
return dist;
} // getGeneratorCanonical
}; // RandomDistribution
typedef RandomEngine RE;
typedef RandomDistribution RD;
// #include "RandomGeneator.inl"
#endif // RANDOM_GENERATOR_H
我正在开发的就是这个功能
template<class RealType = double, std::size_t numBits, class Generator>
static std::generate_canonical<RealType, numBits>& getGenerateCanonical( Generator& engine ) {
static std::generate_canonical<RealType, numBits> dist( engine );
return dist;
} // getGeneratorCanonical
我一直遵循这个网站的语法:cppreference 他们有这行代码
std::cout << std::generate_canonical<double, 10>(gen) << ' ';
我正在尝试创建并 return 此发行版的静态实例。模板参数中的 RealType 默认为 double,最好与 std::generate_canonical
一起使用,std::size_t 是第二个模板参数字段中的位数,第三个模板参数表示 RandomEngine 生成器传递给它。 Howe 我无法正确定义此功能。我不断收到来自 VS2015
1>------ Build started: Project: DieRoll, Configuration: Debug Win32 ------
1> RandomGenerator.cpp
1>c:\users\skilz80\documents\visual studio 2015\projects\dieroll\dieroll\randomgenerator.h(297): error C2988: unrecognizable template declaration/definition
1>c:\users\skilz80\documents\visual studio 2015\projects\dieroll\dieroll\randomgenerator.h(297): error C2143: syntax error: missing ';' before '&'
1>c:\users\skilz80\documents\visual studio 2015\projects\dieroll\dieroll\randomgenerator.h(297): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
1>c:\users\skilz80\documents\visual studio 2015\projects\dieroll\dieroll\randomgenerator.h(297): error C2365: 'std::generate_canonical': redefinition; previous definition was 'function'
1> c:\program files (x86)\microsoft visual studio 14.0\vc\include\random(295): note: see declaration of 'std::generate_canonical'
1>c:\users\skilz80\documents\visual studio 2015\projects\dieroll\dieroll\randomgenerator.h(297): error C2238: unexpected token(s) preceding ';'
1>c:\users\skilz80\documents\visual studio 2015\projects\dieroll\dieroll\randomgenerator.h(297): error C2059: syntax error: '&'
1>c:\users\skilz80\documents\visual studio 2015\projects\dieroll\dieroll\randomgenerator.h(304): error C2143: syntax error: missing ';' before '}'
1>c:\users\skilz80\documents\visual studio 2015\projects\dieroll\dieroll\randomgenerator.h(304): error C2238: unexpected token(s) preceding ';'
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========
我试过其他方法来定义它,但我得到了非常相似的错误。我不需要这些功能来完成实际工作,因为它留给了用户定义,我只是创建一个简单的用户界面,以便快速轻松地创建一个准备好的 RandomEngine 和一个 PreparedDistribution,其中静态生成一个实例,但是用户仍然可以选择创建正在使用的类型的局部变量。任何有关如何正确构造此静态函数的建议都将受到赞赏。
编辑 感谢 ildjarn 提到 std::generate_canonical 是一个函数而不是 class 模板。当我回到我所引用的网站时,他们确实以小绿色文本将其列为函数模板,而不是 class 模板。既然我直接知道它是什么,我就可以从我的 class 中省略它而不用担心它。现在,这消除了我在无法编译时遇到的一些困惑。
编辑
我终于完成了我的 class 并合并了所有主要发行版并测试了它们,它们似乎都可以正常工作。我还删除了 std::uniform_int
和 std::uniform_real
,因为它们只是各自分布的基础 classes。
std::generate_canonical
是函数,不是类型。