I'm implementing a sparse matrix class that using std::unique_ptr to manage pointers to blocks of 2D data matrix. But msvc raise a error when compiling the code:
03.cpp
#include<iostream>
#include"bate.h"
#define N (512*512)
struct Grid{
constexpr static int Bshitft = 8; // 整除用的
constexpr static int B = 1 << Bshitft; // 索引用的
constexpr static int Bmask = B - 1; // 取余用的
constexpr static int B1shitft = 11;
constexpr static int B1 = 1 << B1shitft;
constexpr static int B1mask = B1 - 1;
struct Block{
char m_block[B][B];
};
std::unique_ptr<Block> m_data[B1][B1];
char read(int x, int y) const{
const std::unique_ptr<Block>& block = m_data[(x >> Bshitft) & B1mask][(y >> Bshitft) & B1mask]; // 因为read是const函数,所以类属性的引用需要用const接收
if(!block) return 0; // 如果块指针没有激活,返回0
return block->m_block[x & Bmask][y & Bmask];
}
void write(int x, int y, char value){
std::unique_ptr<Block>& block = m_data[(x >> Bshitft) & B1mask][(y >> Bshitft) & B1mask];
if(!block) block = std::make_unique<Block>(); // 如果指针没有激活,则新建一个块
block->m_block[x & Bmask][y & Bmask] = value;
}
template<class Func>
void foreach(const Func& func){
for(int x1 = 0; x1 < B1; x1++){ // 遍历每个block pointer
for(int y1 = 0; y1 < B1; y1++){
const std::unique_ptr<Block>& block = m_data[x1 & B1mask][y1 & B1mask];
if(!block) continue;
int xb = x1 << Bshitft, yb = y1 << Bshitft;
for(int dx = 0; dx < B; dx++){
for(int dy = 0; dy < B; dy++){
func(xb | dx, yb | dy, block->m_block[dx][dy]);
}
}
}
}
}
};
int main(){
bate::timing("main");
Grid* a = new Grid{};
float px = -100.f, py = 100.f;
float vx = 0.2f, vy = -0.6f;
for(int step = 0; step < N; step++){
px += vx;
py += vy;
int x = (int)std::floor(px);
int y = (int)std::floor(py);
a->write(x, y, 1);
}
int count = 0;
a->foreach([&](int x, int y, char& value){
if(value != 0) ++count;
});
bate::timing("main");
printf("Count=%d", count);
return 0;
}
bate.h
#pragma once
#include <iostream>
#include <vector>
#include <cmath>
#include <random>
#include <cstring>
#include <cstdlib>
#include <string>
#include <array>
#include <tuple>
#include <chrono>
#include <map>
#include <unordered_map>
#include <memory>
namespace bate {
static float frand() {
static std::mt19937 gen;
static std::uniform_real_distribution<float> unif;
return unif(gen);
}
static void timing(std::string const &key) {
static std::map<std::string, std::chrono::steady_clock::time_point> saves;
auto it = saves.find(key);
if (it == saves.end()) {
saves.emplace(key, std::chrono::steady_clock::now());
} else {
double dt = std::chrono::duration_cast<std::chrono::duration<double>>(std::chrono::steady_clock::now() - it->second).count();
std::cout << key << ": " << dt << "s" << std::endl;
}
}
}
CMakeLists.txt
cmake_minimum_required(VERSION 3.20)
set(CMAKE_BUILD_TYPE Release)
set(CMAKE_CXX_STANDARD 20)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
project(main)
add_executable(main 03.cpp)