使用模板独立 enable_if 时,模板化 class 的模板化友元函数出现链接器错误
linker error with templated friend function of templated class when using template independent enable_if
我正在处理带有模板友元函数的模板class
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++ 编译,但在 link 时间失败
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
我观察到的是:
当用依赖于 class 模板的东西替换 enable_if
(类型)的第二个参数时(int
→ decltype(x.hidden)
) see here link使用 g++ 成功。
当创建 hidden
public 并删除友元声明时,代码 link 没问题(因此函数模板被实例化)。
删除 enable_if 并仅将 return 类型声明为 int
工作正常。
将 enable_if 从 return 类型移动到 template <typename … , typename = typename enable_if_t<…>>
,但是这里我无法编译,因为 g++ 和 clang++ 告诉我 friend 声明不允许默认模板参数。
从 friend 声明中删除 enable_if,只保留它在定义中 → fails to link
用clang++编译时linking成功
将函数定义移动到 class 声明中(在现实世界的例子中失败,因为函数应该将各种参数作为可变参数模板,然后我违反了一个 -定义规则,f(X<int>, X<float>)
在 X<int>
定义中定义一次,在 X<float>
定义中定义一次。
这是 g++ (8.2) 的错误还是 clang++ 违反了标准,在后一种情况下,如何触发函数的代码生成?
is this a g++ (8.2) bug or does clang++ violate the standard
我怀疑 gcc 是正确的。模板朋友是语言的阴暗角落
how do I trigger the code generation for the function?
我会通过一个结识的演员来做。
#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);
}
我正在处理带有模板友元函数的模板class
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++ 编译,但在 link 时间失败
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
我观察到的是:
当用依赖于 class 模板的东西替换
enable_if
(类型)的第二个参数时(int
→decltype(x.hidden)
) see here link使用 g++ 成功。当创建
hidden
public 并删除友元声明时,代码 link 没问题(因此函数模板被实例化)。删除 enable_if 并仅将 return 类型声明为
int
工作正常。将 enable_if 从 return 类型移动到
template <typename … , typename = typename enable_if_t<…>>
,但是这里我无法编译,因为 g++ 和 clang++ 告诉我 friend 声明不允许默认模板参数。从 friend 声明中删除 enable_if,只保留它在定义中 → fails to link
用clang++编译时linking成功
将函数定义移动到 class 声明中(在现实世界的例子中失败,因为函数应该将各种参数作为可变参数模板,然后我违反了一个 -定义规则,
f(X<int>, X<float>)
在X<int>
定义中定义一次,在X<float>
定义中定义一次。
这是 g++ (8.2) 的错误还是 clang++ 违反了标准,在后一种情况下,如何触发函数的代码生成?
is this a g++ (8.2) bug or does clang++ violate the standard
我怀疑 gcc 是正确的。模板朋友是语言的阴暗角落
how do I trigger the code generation for the function?
我会通过一个结识的演员来做。
#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);
}