如何防止模板类的实例化?

时间:2018-12-27 04:18:12

标签: c++ templates

我正在研究模板化矩阵类,目前正在研究模板行列式函数。这是一个递归函数,可找到每个子矩阵的确定值直至基本情况,并将每个子确定值相加/相减。功能如下:

@LotsOfAnnotations
class ControllerTest1 {
    @Autowired
    private MyController myController;
    @Test
    public String verboseNameTest() {
        // Mock 3rd party calls
        ....
        // Form request
        MyRequest request = new MyRequest();
        // Invoke testing method
        myController.handle(request);
        // Assert
    }
}

我遇到的问题与模板部分有关。具体来说,这部分代码:

@LotsOfAnnotations
class ControllerTest2 {
    @Autowired
    private TestRestTemplate testTemplate;
    private MockRestServiceServer server;
    @Autowired
    private MockMvc mockMvc;
    @Autowired
    private WebApplicationContext webAppContext;

    @Before
    public void setup() {
        server = MockRestServiceServer.createServer(testTemplate.getRestTemplate());
        mockMvc = MockMvcBuilders.webAppContextSetup(this.webAppContext).build();
    }
    @Test
    public String verboseNameTest() {
        // Mock 3rd party calls
        ....
        // Form request
        String jsonStringRequest = "{}";
        RequestBuilder requestBuilder = MockMvcRequestBuilders
                    .post("/path")
                    .contentType(MediaType.APPLICATION_JSON)
                    .content(jsonStringRequest);
        // Make a call
        MvcResult result = this.mockMvc
                    .perform(requestBuilder)
                    .andExpect(status().isOk())
                    .andReturn();
        // Assert
    }
}

这是要创建一个尺寸适合子矩阵(比当前小1英寸)的矩阵。

正在发生的事情是该特定模板正在实例化:

@LotsOfAnnotations
class ControllerTest2 {
    @Autowired
    private TestRestTemplate testTemplate;
    private MockRestServiceServer server;
    @Autowired
    private MockMvc mockMvc;
    @Autowired
    private WebApplicationContext webAppContext;

    @Before
    public void setup() {
        server = MockRestServiceServer.createServer(testTemplate.getRestTemplate());
        mockMvc = MockMvcBuilders.webAppContextSetup(this.webAppContext).build();
    }
    @Test
    public String verboseNameTest() {
        // Mock 3rd party calls
        ....
        // Form request
        String jsonStringRequest = "{}";
        RequestBuilder requestBuilder = MockMvcRequestBuilders
                    .post("/path")
                    .contentType(MediaType.APPLICATION_JSON)
                    .content(jsonStringRequest);
        // Make a call
        MvcResult result = this.mockMvc
                    .perform(requestBuilder)
                    .andExpect(status().isOk())
                    .andReturn();
        // Assert
    }
}

这是不可行的,因为矩阵中的基础数据是一个数组,并且我们不能有零长度的数组。

1)有什么方法可以防止实例化此特定模板?

2)可能是一个愚蠢的问题,但是我使用传入的Matrix3x3来调用此函数。为什么编译器实例化尺寸从3一直到0的每个模板? (如果可能的话,低级的解释会很好)

2 个答案:

答案 0 :(得分:2)

您可以将Determinant<T, 1>专门化,这样它就不会创建Matrix<T, 0, 0>

template <typename T>
T Determinant<T, 1> (Matrix<T, 1, 1> &mat) {
    // Implementation here
    // Avoid Matrix<T, 0, 0>
}

您还可以专门研究Determinant<T, 2>,以便将if else放到里面,因为最好在编译时检查模板变量。

template <typename T, std::size_t size>
T Determinant<T, size> (Matrix<T, size, size> &mat) {
    // original "else" part here
}

template <typename T>
T Determinant<T, 2> (Matrix<T, 2, 2> &mat) {
    return ((mat.m_data[0][0] * mat.m_data[1][1]) - (mat.m_data[0][1] * mat.m_data[1][0]));
}

答案 1 :(得分:0)

如果您可以访问C ++ 17,则可以使用if constexpr而不是常规的if来实例化“废弃”分支:

if constexpr (size == 2)