以下代码展示了一些有趣的行为:
我的期望输出是:
#include <iostream>
using namespace std;
template<class T>
class B{
public:
void foo(B<T> &x)const;
template<class F> void foo(F f);
};
template<typename T> void B<T>::foo(B<T> &x)const{cout<<"foo_B"<<endl;}
template<typename T> template<typename F> void B<T>::foo(F f){cout<<"foo_F"<<endl;}
int main(){
B<int> a;
B<int> b;
b.foo(a);
b.foo([](){;});
return(0);
}
我的期望输出是:
foo_B
foo_F
但实际输出为
foo_F
foo_F
这取决于是否将void foo(B<T> &x)
声明为const
。如果省略const
,则输出结果符合预期。
此外,如果向void foo(F f)
添加const
,那么输出结果也符合预期。
然而,void foo(B<T> &x)
不会更改this
,而void foo(F f)
会更改this
。因此,当前的布局是所需的。
如何在不放弃const
的情况下解决这个问题,任何想法都会受到欢迎。
b
声明为const
,这意味着需要制作一个副本,例如const c(b);
,然后使用c.foo(a)
。由于两个函数的主体可能有很大不同,忘记后者(即使用b.foo(a)
)会导致段错误。更好的解决方案是使用结构体,让编译器发出警告。 - user1407220B
的特化时的模板重载。 - dfrib