1

建立在这个答案之上:

https://stackoverflow.com/a/3319851/13250135

我想将我的模板参数构造成方案,因为相同的类在同一个应用程序的不同上下文中使用。

// adapted from https://stackoverflow.com/a/3319851
template<typename _string, typename _real>
struct scheme{
    public:
    using string = _string;
    using real = _real;
};

using scheme1 = scheme<std::string_view, double>;
using scheme2 = scheme<std::string, float>;

template<class scheme>
class Test {
    scheme::string text;
    scheme::real value;
    std::array<int, 10> array{};
};

Test<scheme1> test1{};
Test<scheme2> test2{};

到现在为止还挺好。但现在我需要一种本身就是参数的类型。例如,我想std::array<T>用潜在的替代品同样参数化。

编辑:添加更多信息。

我想实现这样的目标:

template<typename _string, typename _real, typename _collection>
struct scheme{
    public:
    using string = _string;
    using real = _real;
    using collection = _collection;
};

using scheme1 = scheme<std::string_view, double, std::array>;
using scheme2 = scheme<std::string, float, myNamespace::myArray>;

template<class scheme>
class Test {
    scheme::string text;
    scheme::real value;
    scheme::collection<int, 10> array{};
};

但当然这不起作用,因为std::array没有参数不是有效的类型名。但我需要能够仅在模板被实例化的地方提供这些最终参数,例如在Test类中。

为什么我会想要这样的东西?

有些类既可用于constexpr方案(显然是所有 const 数据),也可用于各种非 const 方案。例如,我可以将std::string_view, 用于constexpr方案和std::string非常量方案。

另一个示例可能是提供与特定于版本的二进制数据方案(将数据从 32 位迁移到 64 位、代码页到 Unicode 等)中持久保存的数据的兼容性。较新版本的应用程序需要实现所有方案才能在升级后读取旧数据。

谢谢,马克

4

1 回答 1

4

您需要制作_collection一个模板模板参数。

template<typename _string, typename _real, template<typename, size_t> typename _collection>
struct scheme{
    public:
    using string = _string;
    using real = _real;
    // This is now a template type alias, i.e. "variable inside the scheme"
    template<typename T, size_t N>
    using collection = _collection<T, N>;
};

您的Test课程如下所示:

template<class scheme>
class Test {
    scheme::string text;
    scheme::real value;
    // As collection is no longer a type, the additional template disambiguator is needed here...
    scheme::template collection<int, 10> array{};
};

请注意,此解决方案仅适用于具有相同“签名”的模板,std::array即一个类型参数后跟一个整数非类型参数。std::vector例如将不起作用。因此,取决于myNamespace::myArray此解决方案的实际类型,可能不适用于您的问题。

编辑:我意识到您在问题中添加了 c++20 标签。在这种情况下,您可以省略类typename中的三个 s Test。现场代码在这里

于 2021-01-22T16:35:53.167 回答