简单的概念检查

时间:2017-03-06 07:38:46

标签: c++ c++-concepts

说我有一个这样的简单模板:

template<typename T>
class A {};

我想指定类型参数T是某些不相关的类型X<U>,其中U未知(或不可指定)。

有没有办法将其表达为一个概念?

2 个答案:

答案 0 :(得分:30)

  

有没有办法将其表达为一个概念?

您不需要一个概念,类模板专业化在您的情况下也可以正常工作 例如,您可以这样做:

template<typename T>
class A;

template<typename U>
class A<X<U>> { /* ... */ };

这样,除非A使用X<U>形式(其中U未知)进行实例化,否则您将收到编译时错误,因为主要模板没有定义。换句话说,它不适用于所有类型,但X<U>(对于每个U),后者匹配具有正确定义的类模板特化。

请注意,我认为X是已知类型。你的问题并不清楚 无论如何,如果不是,并且您希望为X<U>和每个X接受U表单的类型,您仍然可以执行此操作:

template<typename T>
class A;

template<template<typename> class X, typename U>
class A<X<U>> { /* ... */ };

作为一个最小的工作示例:

template<typename>
struct S {};

template<typename>
class A;

template<typename U>
class A<S<U>> {};

int main() {
    A<S<int>> aSInt;
    A<S<double>> aSDouble;
    // A<char> aChar;
}

A<S<int>>A<S<double>>都很好,示例会编译。如果你切换评论,它就不会再编译,因为A<char>根本没有定义。

作为旁注,如果您不想使用课程模板专业化并且您想要模拟概念(请记住它们不是标准的一部分,并且它们至少要到2020年才能获胜),你可以这样做:

#include<type_traits>

template<typename>
struct X {};

template<typename>
struct is_xu: std::false_type {};

template<typename U>
struct is_xu<X<U>>: std::true_type {};

template<typename T>
struct A {
    static_assert(is_xu<T>::value, "!");
    // ...
};

int main() {
    A<X<int>> aXInt;
    A<X<double>> aXDouble;
    // A<char> aChar;
}

也就是说,给定泛型类型T,静态通过另一个结构(示例中为is_xu)声明其实际类型,该结构验证T是否为X<U>形式1}}(对于每个U)或不是。

我的两分钱:课程模板专业化更容易阅读和理解。

答案 1 :(得分:11)

template <typename T, template <typename> class C>
concept bool Template = requires (T t) { {t} -> C<auto>; };

现在给出一个类模板:

template <typename T>
struct X {};

可以使用以下方法约束类型模板参数:

template <typename T> requires Template<T, X>
class A {};

或:

template <Template<X> T>
class A {};

DEMO

这也适用于从X<U>派生的类型。