c++ - 部分特化可以在特化的参数列表中引用 sizeof(T) 吗?

标签 c++

看看这个简单的代码( godbolt ):

template <typename, int>
struct Foo;

template <typename T>
struct Foo<T, (int)sizeof(T)>;

Clang 会编译它,而 gcc 不会:
error: template argument '(int)(sizeof (T))' involves template parameter(s)
    struct Foo<T, (int)sizeof(T)>;
                  ^~~~~~~~~~~~~~

哪个编译器是正确的,为什么?

最佳答案

根据 https://timsong-cpp.github.io/cppwp/n4140/temp.class.spec#8.1

A partially specialized non-type argument expression shall not involve a template parameter of the partial specialization except when the argument expression is a simple identifier.


sizeof(T)不是一个简单的标识符。

所以 gcc 是对的。

如果合适,可能的解决方法是用类型替换非类型模板参数(包装常量):
template <typename, typename Size>
struct Foo;

template <typename T>
struct Foo<T, std::integral_constant<int, (int)sizeof(T)>>;

Demo

更新版本 temp.class.spec#match-3 (在 CWG1315 之后)允许它:

If the template arguments of a partial specialization cannot be deduced because of the structure of its template-parameter-list and the template-id, the program is ill-formed. [ Example:

template <int I, int J> struct A {};
template <int I> struct A<I+5, I*2> {};     // error

template <int I> struct A<I, I> {};         // OK

template <int I, int J, int K> struct B {};
template <int I> struct B<I, I*2, 2> {};    // OK

— end example ]



所以clang是对的。

关于c++ - 部分特化可以在特化的参数列表中引用 sizeof(T) 吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61293683/

相关文章:

c++ - C++元编程:为每个枚举类型成员创建typedef作为类型

c++ - 如何比较结构中不同索引的元素

c++ - 如何在 MFC 中创建一个线程,用于相对于正在播放的音频文件移动 slider 控件?

c++ - Qt 编码风格 : how to name private variables

c++ - 如何使用 Boost 创建比较器?

c++ - wxWidgets 透明 wxTextCtrl

c++ - 找不到 Sphinx Ubuntu 14 c++ sphinx_config.h

c++ - 他们如何使 "Get Windows 10"图标默认具有 "Show icon and notifications"可见性?

c++ - 在不丢失数据的情况下将子类对象存储在同一个容器中?

c++ - 查找目录中所有 .cpp .h 文件的常规方法(include、src 等...)