【问题标题】:How to provide deduction guide for nested template class?如何为嵌套模板类提供推演指南?
【发布时间】:2018-02-16 14:10:28
【问题描述】:

根据[temp.deduct.guide/3]:

(...) 应在与 相应的类模板,对于成员类模板,使用 相同的访问。 (...)

但下面的示例似乎在 [gcc][clang] 中都无法编译。

#include <string>

template <class>
struct Foo {
    template <class T>
    struct Bar {
        Bar(T) { }
    };
    Bar(char const*) -> Bar<std::string>;
};

int main() {
    Foo<int>::Bar bar("abc");
    static_cast<void>(bar);
}

嵌套模板类的推导指南的正确语法是什么?或者也许这个是正确的,但编译器还不支持?


类似的语法但没有嵌套类在 gcc 和 clang 中编译得很好:
#include <string>

template <class T>
struct Bar {
    Bar(T) { }
};
Bar(char const*) -> Bar<std::string>;

int main() {
    Bar bar("abc");
    static_cast<void>(bar);
}

【问题讨论】:

  • 在 GCC 中这是一个错误,因为它认为你声明了一个函数。
  • @Someprogrammerdude 我不确定它是否是正确的语法 - 标准中没有相应的示例,但它提到了这种情况......
  • 如果父类没有被模板化,嵌套模板推导指南有效......
  • @AndyG 是的,语法似乎是正确的

标签: c++ templates c++17 template-argument-deduction


【解决方案1】:

[temp.deduct.guide] 包含句子:

deduction-guide 应声明在与相应类模板相同的范围内,并且对于成员类模板,具有相同的访问权限。

这表明您的示例应该可以工作 - 成员类模板明确支持演绎指南,只要它们在相同的范围和访问权限中声明(这将是类范围和 public - 检查并检查) .

这是gcc bug 79501(由理查德·史密斯归档)。

【讨论】:

  • @W.F.您的外部类是类模板,此错误中的示例更简单。应该提交一个 llvm 错误。
  • 是的,这绝对表明语法应该是正确的。我会尝试提交一个错误然后......
  • 刚刚提交llvm bug 34520
  • 根据 Richard 的说法,这是一个缺陷。请参阅PR35107 上的评论 #1。
【解决方案2】:

如果您真的需要临时快速修复,请考虑使用特定于编译器的指令。

Here, on godbolt

关键是通过添加特定于编译器的指令来处理 GCC 和 Clang 之间的行为差​​异。
这是次优的方式,但如果您在项目中被阻止,它可能会帮助您等待编译器补丁。

查看我对这篇文章的回答:https://stackoverflow.com/a/66888013/10883423

#include <string>

template <class>
struct Foo {
    template <class T>
    struct Bar {
        Bar(T) { }
    };
    #if __clang__
    Bar(char const*) -> Bar<std::string>;
    #endif
};

void instanciate_symbols()
{
    [[maybe_unused]] auto bar = Foo<int>::Bar{"abc"};
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-06-20
    • 1970-01-01
    • 2019-09-23
    • 2021-11-19
    • 2019-04-15
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多