我认为一个显式的实例化请求也会自动实例化所有基类成员,但我linker error: unresolved external symbol "public: void Base<int>::foo(int)"
在使用Visual Studio 2008或2010构建此代码时得到了一个.
请注意,向foo()
内部添加调用会bar()
强制编译器实例化Base<int>::bar()
并且构建成功,因此编译器似乎具有实例化所需的所有信息foo()
.
显然,Base<int>
在source.cpp中显式实例化允许构建成功,但是在显式实例化派生类时,需要显式实例化任何依赖基类似乎很愚蠢.
这是正常的吗?我无法找到关于这个问题的标准.
header.h
template<typename T>
class Base {
public:
void foo();
};
template<typename T>
class Derived : public Base<T> {
public:
void bar();
};
Run Code Online (Sandbox Code Playgroud)
source.cpp
#include "header.h"
template<typename T>
void Base<T>::foo() { }
template<typename T>
void Derived<T>::bar() {
// this->foo(); // adding this forces instantiation of foo()???
}
template class Derived<int>;
Run Code Online (Sandbox Code Playgroud)
main.cpp中
#include "header.h"
int main() { …
Run Code Online (Sandbox Code Playgroud) 我想以最小的偏差反复产生快速随机混洗.
众所周知,只要基础随机数发生器(RNG)是无偏的,Fisher-Yates shuffle就是无偏的.
To shuffle an array a of n elements:
for i from n ? 1 downto 1 do
j ? random integer with 0 ? j ? i
exchange a[j] and a[i]
Run Code Online (Sandbox Code Playgroud)
但是如果RNG有偏差(但很快)怎么办?
假设我想生成25个元素数组的许多随机排列.如果我使用具有偏置RNG的Fisher-Yates算法,那么我的置换将是有偏差的,但我相信这假设25元素阵列在每次应用混洗算法之前从相同的状态开始.例如,一个问题是如果RNG只有2 ^ 32~10 ^ 9的周期,我们就不能产生25个元素的每个可能的排列,因为这是25!~10 ^ 25个排列.
我的一般问题是,如果我在开始Fisher-Yates shuffle的每个新应用之前将洗牌后的元素拖垮,这会减少偏差和/或允许算法产生每个排列吗?
我的猜测是它通常会产生更好的结果,但似乎如果重复洗牌的阵列有许多与基础RNG相关的元素,那么排列实际上可能比预期更频繁地重复.
有谁知道任何解决这个问题的研究?
作为一个子问题,如果我只想重复排列数组中25个元素中的5个元素,那么我使用Fisher-Yates算法选择5个元素并在完成一个完整的shuffle之前停止?(我使用交换的数组末尾的5个元素.)然后我重新使用前面部分改组的25个元素数组来选择另一个5的排列.再次,看起来这比从如果基础RNG有偏差,则原始的25个元素数组.有什么想法吗?
我认为测试部分shuffle案例会更容易,因为25个元素中有5个元素只有6,375,600个可能的排列,所以有没有简单的测试来检查偏差?
这个示例代码有效吗?
#include<vector>
using namespace std;
int main() {
vector<int> vec(10); // create with 10 elements
vec.reserve(100); // set capacity to 100
vector<int>::iterator iter = vec.end(); // points 1 past vec[9]
vec.push_back( 777 );
bool is_this_valid_and_true = *iter == vec[10]; // ?
// VS2010 runtime error in debug build:
// Expression: vector iterator not dereferencable
// Works in release build
iter = vec.end() + 1; // points 2 past vec[10]?
vec.push_back( 888 );
vec.push_back( 999 );
is_this_valid_and_true = *iter == vec[12]; …
Run Code Online (Sandbox Code Playgroud)