推断依赖的非类型模板参数

问题描述 投票:0回答:1

类在数组上进行模板化,该数组代表该类的特定配置。这允许在编译时检查配置。这是一个完整的简单示例:

#include <array>

template<std::size_t config_size, const std::array<int, config_size>& config>
class MyClass
{
public:
    MyClass();
private:
    static constexpr bool configIsValid() ;
};

template<std::size_t config_size, const std::array<int, config_size>& config>
MyClass<config_size, config>::MyClass()
{
    static_assert(configIsValid());
}

template<std::size_t config_size, const std::array<int, config_size>& config>
constexpr bool MyClass<config_size, config>::configIsValid()
{
    return (config.size() > 3);
}

int main()
{
    static constexpr std::array<int, 4> valid_config{1,2,3,4};
    MyClass<4, valid_config> a;
    
    static constexpr std::array<int, 3> invalid_config{5,6,7};
    // MyClass<3, invalid_config> b; // This will fail to compile

    return 0;
}

这没问题,但是第一个模板参数可以从第二个模板参数推断出来,所以我更愿意写:

MyClass<config> m;

代替:

MyClass<config_size, config> m;

有什么办法可以做到这一点吗?

数组可能会被包装,但我无法使用不同的容器。

c++ templates non-type-template-parameter
1个回答
0
投票

我认为你提出的问题的答案是“不,你不能”——必须指定非类型模板参数的类型。

还有一些替代方法:

在 C++20 中,您可以编写一个

consteval
函数,它返回正确类型的实例。

template<typename C>
consteval auto deduceMyClass(C& config) {
  // Unnecessary but possible: static_assert(std::is_same_v<std::array<int, config.size()>, C>);
  return MyClass<config.size(), config>{};
}

在 C++17(也可能是 14 和 11,我的记忆很模糊)中,您可以为此使用推导指南,但代价是使配置引用构造函数参数而不是模板参数。

© www.soinside.com 2019 - 2024. All rights reserved.