c++ - 使用独立于模板的 enable_if 时,模板类的模板友元函数的链接器错误
问题描述
我正在处理一个带有模板化友元函数的模板化类
template<typename T>
struct X {
template<typename someX>
auto friend f (someX x) -> std::enable_if_t<std::is_same_v<decltype(x.hidden), int>, int>;
private:
T hidden = 42;
};
template<typename someX>
auto f(someX x) -> std::enable_if_t<std::is_same_v<decltype(x.hidden), int>, int> {return x.hidden;}
这可以用 g++ 编译,但在链接时失败
int main () {
X<int> x;
std::cout << f(x);
}
和
prog.cc:(.text+0x15): undefined reference to `std::enable_if<is_same_v<decltype ({parm#1}.hidden), int>, int>::type f<X<int> >(X<int>)'
collect2: error: ld returned 1 exit status
看这里。
我观察到的是:
当用依赖于类模板( → )
enable_if
的东西替换(类型)的第二个参数时,请参见此处链接成功使用 g++。int
decltype(x.hidden)
当
hidden
公开并删除朋友声明时,代码链接正常(因此函数模板被实例化)。删除 enable_if 并仅将返回类型声明为
int
工作正常。将 enable_if 从返回类型移到
template <typename … , typename = typename enable_if_t<…>>
,但在这里我无法编译,因为 g++ 和 clang++ 告诉我朋友声明不允许默认模板参数。从朋友声明中删除 enable_if 并仅将其保留在定义中 →链接失败
当使用 clang++ 编译链接成功时
将函数定义移动到类声明中(在现实世界的示例中失败,因为该函数应该将各种参数作为可变参数模板,然后我违反了单一定义规则,在
f(X<int>, X<float>)
定义中定义了一次,X<int>
然后在X<float>
定义。
这是 g++ (8.2) 错误还是 clang++ 违反标准,在后一种情况下,如何触发函数的代码生成?
解决方案
这是一个 g++ (8.2) 错误还是 clang++ 违反了标准
我怀疑 gcc 是正确的。模板朋友是语言的一个黑暗角落。
如何触发函数的代码生成?
我会通过一个结识的演员来做。
#include <iostream>
struct friend_of_f
{
template<class someX>
static auto apply(someX x) -> std::enable_if_t<std::is_same_v<decltype(x.hidden), int>, decltype(x.hidden)>
{
return x.hidden;
}
};
template<typename someX>
auto f(someX x) -> decltype(friend_of_f::apply(x))
{
return friend_of_f::apply(x);
}
template<typename T>
struct X
{
friend friend_of_f;
private:
T hidden = 42;
};
int main () {
X<int> x;
std::cout << f(x);
X<double> y;
// std::cout << f(y);
}
推荐阅读
- powerbi - 以编程方式更改 power bi 中的数据集 SQL 语句
- css - 如何设置 CSS 类名来自 ngFor 内部的 json 对象数组 | 角 6
- json - 颠簸,沿数组复制值
- r - 向 x 轴添加嵌套/分组级别
- bash - Linux:将值附加到文件中、特定行的末尾以及文件底部(如果有“键”)
- file - 问题打开和关闭文件以通过电子邮件发送 python
- ansible - AWX ec2 库存多标签过滤器
- html - 为非输入元素保留标签输入关系的最佳元素?
- mysql - 在数据库中使用循环外键引用
- swift - 如何从应用程序包 I macOS 中的文件中读取数据?