显式实例化定义:类模板的构造函数模板——可能吗?(Clang 与 GCC)

Explicit instantiation definition: constructor template of class template -- is it possible? (Clang versus GCC)

提问人:Vittorio Romeo 提问时间:3/17/2023 更新时间:3/17/2023 访问量:149

问:

请考虑以下类模板:

template <typename> 
struct S 
{
    template <typename T>
    void f(T) { /* ... */ }
};

可以提供自身和以下两者的显式实例化定义(或声明):extern templateSS::f

template struct S<int>;
template void S<int>::f<int>(int);

但是,如果我们与构造函数模板完全相同的情况,而不是常规成员函数模板呢?

template <typename> 
struct S 
{
    template <typename T>
    S(T) { /* ... */ }
};

根据 Clang 的说法,仍然可以为自己提供一个显式的实例化定义,但不能为构造函数提供:S

template struct S<int>;       // OK
template S<int>::S<int>(int); // ERROR (!)
error: out-of-line constructor for 'S' cannot have template arguments
template S<int>::S<int>(int);
                 ^~~~~~

另一方面,海湾合作委员会似乎接受这两种定义。在 godbolt.org 上查看此实时示例


模板 S<int>::S<int>(int) 等定义是否合法,或者 Clang 拒绝它是否正确?

C++ C++11 语言律师 显式实例化

评论

1赞 Vesk 3/17/2023
我认为总的来说,GCC 接受的东西比 Clang 多得多。Clang 通常要严格得多,尽管我认为有一些选项可以允许 C++ 对规范进行“扩展”,就像 GCC 接受的规范一样。
1赞 StoryTeller - Unslander Monica 3/17/2023
否,c'tor 声明符 id 中的模板参数列表在 C++20 之后无效。以前从未真正有效,但意外地变得有效了一段时间。这被标记为 LL,所以我不知道你是否真的想出如何修复代码,但在显式实例化中作为声明符是有效的。实际上,任何 c'tor 的模板参数都可以从 c'tor 函数参数中推导出来,可以显式实例化。S<int>::S(int)
0赞 Vittorio Romeo 3/18/2023
@StoryTeller-UnslanderMonica:在我的实际用例中,构造函数的模板参数不是函数参数列表的一部分,因为它是一个约束。运气好吗?enable_if
0赞 StoryTeller - Unslander Monica 3/18/2023
可悲的是没有。我想一种选择是将约束转换为未使用的默认函数参数类型(c++03,复古样式)。但这是黑暗中的一枪,因为我不知道过载设置,所以它也可能不愉快。
1赞 Brian Bi 3/18/2023
你能编辑你的代码来显示实际的用例吗?我很难理解如何拥有一个具有不可推导的模板参数但仍然可用的构造函数模板。

答: 暂无答案