0

我正在尝试创建一个使用数组值作为值/类型模板参数的类。见下文

template< std::array<bool, M> arr>
class gf {
...
};

我相信我这样做的理由是理智的。此类为加法和乘法实现运算符重载。只有当类的实例使用相同的值和大小进行实例化时,这些操作才被明确定义arr

一个示例用例:

std::array<bool,3> p1 = {0,0,1};
std::array<bool,3> p2 = {0,1,1};

gf<p1> a;
gf<p1> b;
gf<p2> c;

auto out1 = a + b; // works as both instances use p1
auto out1 = a + c; // Compiler error as we're adding incompatible types

我目前的工作是传递arr给构造函数调用并在组合任何不兼容的类型时抛出错误。我希望有更好的方法来做到这一点,谢谢!

编辑:此外,任何其他可能实现相同目标的设计模式都将受到欢迎。我不喜欢使用模板专业化,但它是我熟悉的工具!

4

1 回答 1

1

纯粹从技术方面来看,您可以(1)将具有静态存储持续时间的数组的地址constexpr作为非类型模板参数传递:

#include <array>

template<const auto& arr>
struct gf {
    gf& operator+=(const gf& /* rhs */) {
        // ...
        return *this;
    }
};

template<const auto& arr>
auto operator+(gf<arr> lhs, const gf<arr>& rhs) {
    lhs += rhs;
    return lhs;
}

int main() {
    // As we want to use the address of the constexpr std::array
    // at compile time, it needs to have static storage duration.
    static constexpr std::array<bool, 3U> p1{{0, 0, 1}};
    static constexpr std::array<bool, 3U> p2{{0, 1, 1}};
    
    gf<p1> a;
    gf<p1> b;
    gf<p2> c;
    
    auto out1 = a + b;  // OK.
    //auto out2 = a + c;  // Error: incompatible types.
}

这样gf具有唯一数组对象的类模板的每个实例化都将成为唯一类型(/specialization)。

这依赖于 C++17auto作为模板参数;对于类似的 C++11 方法:

#include <array>

template<std::size_t M, const std::array<bool, M>& arr>
struct gf {
    gf& operator+=(const gf& /* rhs */) {
        // ...
        return *this;
    }
};

template<std::size_t M, const std::array<bool, M>& arr>
gf<M, arr> operator+(gf<M, arr> lhs, const gf<M, arr>& rhs) {
    lhs += rhs;
    return lhs;
}

int main() {
    // As we want to use the address of the constexpr std::array
    // at compile time, it needs to have static storage duration.
    static constexpr std::array<bool, 3U> p1{{0, 0, 1}};
    static constexpr std::array<bool, 3U> p2{{0, 1, 1}};
    
    gf<3U, p1> a;
    gf<3U, p1> b;
    gf<3U, p2> c;
    
    auto out1 = a + b;  // OK.
    //auto out2 = a + c;  // Error: incompatible types.
}

(1)无论如何,这个答案都没有试图将其作为任何一种好的方法来解决 OP 的 XY 式问题。

于 2020-07-20T01:10:10.310 回答