簡體   English   中英

使用 enable_if 基於文字類型的類模板特化

[英]class template specialization based on literal type using enable_if

我正在嘗試創建一個 Vector 類,以類型T和元素數量NUM_VALUES為模板。 我希望該類在NUM_VALUES > 16384時使用std::vector存儲其元素,並在NUM_VALUES <= 16384. 16384 時使用std::array<T, NUM_VALUES>存儲其元素。起初我嘗試執行以下操作:

矢量.h:

#include <array>
#include <vector>

#include <cstddef>

template <typename T, std::size_t NUM_VALUES, typename Elements = std::vector<T>>
class Vector
{
public:
    constexpr const char* hello()
    {
        return "hello";
    }
};

template <typename T, std::size_t NUM_VALUES>
class Vector<T, NUM_VALUES, typename std::enable_if<NUM_VALUES <= 16384, std::array<T, NUM_VALUES>>::type>
{
public:
    constexpr const char* hello()
    {
        return "Hello";
    }
};

主文件

#include "vector.h"

#include <iostream>

int main()
{
    Vector<int, 10> vec1;
    Vector<int, 1000000> vec2;
    std::cout << vec1.hello() << ", " << vec2.hello();
    return 0;
}

然而,這總是選擇主模板,所以我得到“hello”、“hello”而不是“hello”、“Hello”。 我嘗試通過將 vector.h 更改為:

#include <array>
#include <vector>

#include <cstddef>

template <typename T, std::size_t NUM_VALUES, typename Elements = typename std::enable_if<16384 < NUM_VALUES, std::vector<T>>::type>
class Vector
{
public:
    constexpr const char* hello()
    {
        return "hello";
    }
};

template <typename T, std::size_t NUM_VALUES>
class Vector<T, NUM_VALUES, typename std::enable_if<NUM_VALUES <= 16384, std::array<T, NUM_VALUES>>::type>
{
public:
    constexpr const char* hello()
    {
        return "Hello";
    }
};

但得到了錯誤:

\MyVector\main.cpp(7,16): error C2146: syntax error: missing '>' before identifier 'type'
\MyVector\MyVector\main.cpp(7,2): error C2976: 'Vector': too few template arguments
\MyVector\MyVector\vector.h(9): message : see declaration of 'Vector'
\MyVector\MyVector\main.cpp(7,18): error C2146: syntax error: missing '>' before identifier 'type'
\MyVector\MyVector\main.cpp(7): error C2641: cannot deduce template arguments for 'Vector'
\MyVector\MyVector\main.cpp(7): error C2783: 'Vector<T,NUM_VALUES,Elements> Vector(void)': could not deduce template argument for 'T'
\MyVector\MyVector\vector.h(9): message : see declaration of 'Vector'
\MyVector\MyVector\main.cpp(7): error C2783: 'Vector<T,NUM_VALUES,Elements> Vector(void)': could not deduce template argument for 'NUM_VALUES'
\MyVector\MyVector\vector.h(9): message : see declaration of 'Vector'
\MyVector\MyVector\main.cpp(7,22): error C2780: 'Vector<T,NUM_VALUES,Elements> Vector(Vector<T,NUM_VALUES,Elements>)': expects 1 arguments - 0 provided
\MyVector\MyVector\vector.h(9): message : see declaration of 'Vector

我正在使用 Visual Studio 2022 來編譯代碼。

SFINAE 類型不是 C++ 標准的一部分,但您可以通過不同的方式輕松實現所需的結果。

為兩種備選方案定義單獨的模板。 然后定義一個別名模板Vector ,它使用std::conditional_t來確定要使用的類型:

constexpr std::size_t SmallVectorMaxSize = 16384;

template <typename T, std::size_t NUM_VALUES>
class BigVector
{
public:
    static_assert(NUM_VALUES > SmallVectorMaxSize);

    using Elements = std::vector<T>;

    constexpr const char* hello()
    {
        return "hello";
    }
};

template <typename T, std::size_t NUM_VALUES>
class SmallVector
{
public:
    static_assert(NUM_VALUES <= SmallVectorMaxSize);

    using Elements = std::array<T, NUM_VALUES>;

    constexpr const char* hello()
    {
        return "Hello";
    }
};

template<class T, size_t N>
using Vector = std::conditional_t<N <= SmallVectorMaxSize, SmallVector<T, N>, BigVector<T, N>>;

int main()
{
    Vector<int, 10> vec1;
    Vector<int, 1000000> vec2;
    std::cout << vec1.hello() << ", " << vec2.hello();
    return 0;
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM