msvc compilation bug of sparse matrix

杰 谭 21 Reputation points
2022-10-03T12:33:59.517+00:00

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:247023-x8t6y7t9tetihcnndqo.png

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)  
C++
C++
A high-level, general-purpose programming language, created as an extension of the C programming language, that has object-oriented, generic, and functional features in addition to facilities for low-level memory manipulation.
3,785 questions
{count} votes

Accepted answer
  1. Viorel 118.5K Reputation points
    2022-10-03T14:38:59.053+00:00

    To work around the problem, try avoiding large member arrays. For example:

    struct Grid  
    {  
        . . .  
    
        using Matrix = std::unique_ptr<Block>[B1][B1];  
        std::unique_ptr<Matrix> m_data;  
    
        Grid( )  
            : m_data( (Matrix*)new Matrix )  
        {  
        }  
    };  
    

    To access the values, use expressions like _(*m_data)[a][b]_.

    I think that the problem can be reported here: https://developercommunity.visualstudio.com/search?space=62.

    0 comments No comments

0 additional answers

Sort by: Most helpful

Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.