gpt4 book ai didi

c++ - 编译类型模板谓词使用 Clang 进行编译,但不使用 GCC 或 MSVC

转载 作者:塔克拉玛干 更新时间:2023-11-03 02:06:54 26 4
gpt4 key购买 nike

考虑以下 C++ 代码:

#include <type_traits>

template<int x, int y, bool visible>
struct Point { };

template<typename T>
struct Predicate : std::false_type { };

template<typename... Types, Types... Values, template<Types...> class Head>
struct Predicate<Head<Values...>> : std::true_type { };

static_assert(Predicate<Point<1, 2, true>>::value, "assert");

Predicate 的目的是识别具有任意模板类名称(绑定(bind)到 Head )的模板实例化,它存储零个或多个非类型模板参数,可能是不同类型,并且没有其他参数(类型或模板)。此代码使用 Clang 成功编译,但 GCC 给出错误:

<source>:10:29: error: expansion pattern '<anonymous>' contains no parameter packs

struct Predicate<Head<Values...>> : std::true_type { };
^~~

MSVC 也提示:

<source>(10): error C2764: 'Types': template parameter not used or deducible in partial specialization 'Predicate<Head<Values...>>'

哪个编译器是正确的,C++ 标准在这个主题上是怎么说的?


我注意到使用 C++17,GCC 的错误可以通过这种方式解决:

template<auto... Values, template<auto...> class Head>
struct Predicate<Head<Values...>> : std::true_type { };

但是这个版本还是一样的错误:

template<auto... Values, template<decltype(Values)...> class Head>
struct Predicate<Head<Values...>> : std::true_type { };

最佳答案

GCC 和 MSVC 是正确的。

来自 [temp.param]/19 :

If a template-parameter is a type-parameter with an ellipsis prior to its optional identifier or is a parameter-declaration that declares a pack ([dcl.fct]), then the template-parameter is a template parameter pack. A template parameter pack that is a parameter-declaration whose type contains one or more unexpanded packs is a pack expansion. Similarly, a template parameter pack that is a type-parameter with a template-parameter-list containing one or more unexpanded packs is a pack expansion. A template parameter pack that is a pack expansion shall not expand a template parameter pack declared in the same template-parameter-list. [ Example:

template <class... Types>                       // Types is a template type parameter pack
class Tuple; // but not a pack expansion

template <class T, int... Dims> // Dims is a non-type template parameter pack
struct multi_array; // but not a pack expansion

template <class... T>
struct value_holder {
template <T... Values> struct apply { }; // Values is a non-type template parameter pack
}; // and a pack expansion

template <class... T, T... Values> // error: Values expands template type parameter
struct static_array; // pack T within the same template parameter list

— end example ]

关于c++ - 编译类型模板谓词使用 Clang 进行编译,但不使用 GCC 或 MSVC,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51717440/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com