使用模板独立的enable_if时,模板化类的模板化友元函数的链接器错误

问题描述 投票:1回答:1

我正在处理带有模板化朋友函数的模板化类

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

see here

我观察到的是:

  • 当用依赖于类模板的东西替换enable_if(类型)的第二个参数时(intdecltype(x.hidden)see here链接成功与g ++。
  • 当使hidden公开并删除友元声明时,代码链接正常(因此函数模板被实例化)。
  • 删除enable_if只是声明返回类型为int工作正常。
  • 将enable_if从返回类型移动到template <typename … , typename = typename enable_if_t<…>>,但是在这里我无法编译,因为g ++和clang ++告诉我朋友声明不允许默认模板参数。
  • 从友元声明中删除enable_if,并将其保留在定义→qazxsw poi中
  • 用clang ++编译时链接成功
  • 将函数定义移动到类声明中(在现实世界示例中失败,因为该函数应该将各种参数作为可变参数模板,然后我违反了单定义规则,在fails to link定义中定义了一次f(X<int>, X<float>)并且曾经在X<int>定义。

这是一个g ++(8.2)错误还是clang ++违反了标准,在后一种情况下,我该如何触发函数的代码生成?

c++ templates g++ friend-function
1个回答
1
投票

这是一个g ++(8.2)错误,还是clang ++违反了标准

我怀疑gcc是正确的。模板朋友是语言的一个黑暗角落。

如何触发函数的代码生成?

我是通过一个友好的演员来做的。

X<float>
© www.soinside.com 2019 - 2024. All rights reserved.