模板友元函数和返回类型推导
Template friend function and return type deduction
注意:这个问题非常接近类友元函数的返回类型推导,但我在那里没有找到问题的答案。
使用 clang 3.4 和 std=c++1y 和 clang 3.5 测试 std=c++14 和 std=c++1z 进行测试
此代码编译:
#include <iostream>
template<class T>
class MyClass {
public:
MyClass(T const& a) : impl(a) {}
template<class T0, class T1> friend auto
// requires operator+(T0,T1) exists
operator+(MyClass<T0> const& a, MyClass<T1> const& b)
{
return MyClass<decltype(a.impl+b.impl)>{a.impl + b.impl};
}
T getImpl() const { return impl; }
private:
T impl;
};
int main() {
MyClass<int> x(2);
MyClass<long> y(2);
auto z = x+y;
std::cout << z.getImpl() << "n";
}
现在,如果我在类之外定义 operator+,它不再编译:
template<class T>
class MyClass {
public:
MyClass(T const& a) : impl(a) {}
template<class T0, class T1> friend auto
operator+(MyClass<T0> const& a, MyClass<T1> const& b);
T getImpl() const { return impl; }
private:
T impl;
};
template<class T0, class T1> auto
operator+(MyClass<T0> const& a, MyClass<T1> const& b)
{
return MyClass<decltype(a.impl+b.impl)>{a.impl + b.impl};
}
叮当 3.4 说:
error: use of overloaded operator '+' is ambiguous (with operand types MyClass<int> and MyClass<long>)
然后指出它认为是两个不同的函数:类中的声明和类外的定义。
我的问题是:这是一个叮当错误,还是只是为朋友函数推断出模板参数,从而导致两个函数在某些情况下不等效?你会建议什么替代方案:使 operator+ 成为成员函数,或者在类中定义 friend operator+(在我看来,这会使类接口混乱)?
仅供您参考,我有一个此类代码的真实用例,我尝试包装第三方矩阵类,并且由于使用表达式模板进行惰性计算,我需要返回类型推断。
编辑:以下内容确实有效(但仍然使界面混乱...
template<typename T>
class MyClass
{
T impl;
public:
explicit MyClass(T a) : impl(std::move(a)) { }
T const& getImpl() const { return impl; }
template<typename T0, typename T1>
friend auto operator +(MyClass<T0> const& a, MyClass<T1> const& b) -> MyClass<decltype(a.impl + b.impl)>;
};
template<typename T0, typename T1>
auto operator +(MyClass<T0> const& a, MyClass<T1> const& b) -> MyClass<decltype(a.impl + b.impl)>
{
return MyClass<decltype(a.impl + b.impl)>(a.impl + b.impl);
}
编辑:看看评论部分,这是 GCC 4.8.2 和 4.9 中的一个错误
GCC 错误代码:
prog.cpp:10:61:错误:非静态数据成员声明为"auto" operator+(MyClass const& a, MyClass const& b) ^ prog.cpp: 在函数 'int main()' 中: prog.cpp:25:15: error: no match 对于"运算符+"(操作数类型为"MyClass"和"MyClass") 自动 z = x+y; ^
- 如何获取std::result_of函数的返回类型
- 如何建立使用模板函数的lambda函数的尾部返回类型
- 在没有定义返回类型的函数中返回布尔值,并将结果保存在无错误的char编译中-为什么
- 特征::矩阵<双精度,1,3> 结构类型函数中的返回类型函数
- 函数作为模板参数,是否对返回类型强制约束
- C++中函数的向量返回类型引发错误
- 检查函数返回类型是否与STL容器类型值相同
- 警告:在函数返回类型 [-Wignore 限定符] 时忽略类型限定符
- 为什么 c++(g++) 不允许模板返回类型和函数名称之间有空格?
- 为什么返回类型的'const'限定符对标有 __forceinline/内联的函数没有影响?
- 在 c++ 中将函数返回类型指定为模板参数
- 使用 SWIG 更改生成的 CS 函数中的返回类型
- C++ 这里有一个返回 (24) 的布尔返回类型函数
- 使用SFINAE来检测void返回类型函数的存在
- 模板返回类型函数如何在C++中工作
- 如何在返回类型函数模板的专用化中使用派生类型?( "couldn't infer template argument" )
- Bon appetit :从 int 返回类型函数在 main() 中打印字符串
- 在引用或指针返回类型函数上输入
- 在后面的返回类型函数语法中,auto关键字背后是否有意图
- 我可以在c++中重写字符串返回类型函数吗?