模板中的概念与类型名称参数

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

我很好奇这是否是 C++23 中定义的行为,即具有接受

template
template
-
typename
,并且能够插入接受
template
concept
(其中
accepts 
typename
)?

这是一个例子:

#include <iostream>
#include <type_traits>

template<typename T>
concept MyConcept = std::is_integral_v<T> || std::is_floating_point_v<T>;

template<template<typename> typename TT>
struct A {
    template<typename T>
    using Type = TT<T>;
};


template<MyConcept T>
struct B {
    T bb;
};

int main(int argc, char** args)
{
    auto a = A<B>{}; // Ok? Compiles with gcc 13.2.1 and clang-16.0.6
    auto b = decltype(a)::Type<int>{};
    return 0;
}

相反的情况似乎也可以编译,这让我更加怀疑


template<template<MyConcept> typename TT>
struct A {
    template<typename T>
    using Type = TT<T>;
};


template<typename T>
struct B {
    T bb;
};

int main(int argc, char** args)
{
    auto a = A<B>{}; // Ok? Compiles with gcc 13.2.1 and clang-16.0.6
    auto b = decltype(a)::Type<int>{};
    return 0;
}

这里,在一定的读数下,我们应该接受一个

template
template
-
template
iff,模板接受一个
MyConcept
,但是
B
template
是不受约束的?

这些示例中的任何一个都是未定义的行为,还是它们的行为符合标准定义?

谢谢!

c++ templates standards undefined-behavior c++23
1个回答
0
投票

根据公开可用的 C++23 标准工作草案,这似乎是“已定义”行为并且是正确的。 § 13.4.4 第 3 段下的示例 4 似乎准确地表明了这一点,根据标准: template<typename T> concept C = requires (T t) { t.f(); }; template<typename T> concept D = C<T> && requires (T t) { t.g(); }; template<template<C> class P> struct S { }; template<C> struct X { }; template<D> struct Y { }; template<typename T> struct Z { }; S<X> s1; // OK, X and P have equivalent constraints S<Y> s2; // error: P is not at least as specialized as Y S<Z> s3; // OK, P is at least as specialized as Z

示例 2 中的这一点看起来也很相关:

template<auto n> class D { /* ... */ }; //... template<template<int> class R> class Z { /* ... */ }; //... Z<D> zd; // OK

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