如何为嵌套模板类提供演绎指南?

时间:2017-09-07 18:41:00

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

根据[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);
}

2 个答案:

答案 0 :(得分:11)

[temp.deduct.guide]包括以下句子:

  

演绎指南应在与相应类模板相同的范围内声明,对于成员类模板,具有相同的访问权限。

这表明您的示例应该有效 - 只要在同一范围和访问中声明了成员类模板,它们就会明确支持演绎指南(这将是类范围和public - 检查并检查)。

这是gcc bug 79501(由Richard Smith提交)。

答案 1 :(得分:1)

如果您确实需要临时快速修复,请考虑使用特定于编译器的说明。

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"};
}