在我的库中尝试为 const 和非 const 模板参数提供函数时,我遇到了一个奇怪的问题。以下源代码是一个最小的示例现象:
#include <iostream>
template<typename some_type>
struct some_meta_class;
template<>
struct some_meta_class<int>
{
typedef void type;
};
template<typename some_type>
struct return_type
{
typedef typename some_meta_class< some_type >::type test;
typedef void type;
};
template<typename type>
typename return_type<type>::type foo( type & in )
{
std::cout << "non-const" << std::endl;
}
template<typename type>
void foo( type const & in )
{
std::cout << "const" << std::endl;
}
int main()
{
int i;
int const & ciref = i;
foo(ciref);
}
我试图为 foo 实现一个非 const 版本和一个 const 版本,但不幸的是,这段代码无法在 CLANG 3.0 和 gcc 4.6.3 上编译。
main.cpp:18:22:错误:未定义模板“some_meta_class”的隐式实例化
因此,出于某种原因,编译器希望将非 const 版本的 foo 用于 const int 引用。这显然会导致上面的错误,因为 some_meta_class 没有实现。奇怪的是,如果您进行以下更改之一,代码编译得很好并且可以工作:
- 取消注释/删除非常量版本
- 取消注释/删除 return_type::test 的 typedef
这个例子当然是简约和纯粹的学术。在我的库中,我遇到了这个问题,因为 const 和非 const 版本返回不同的类型。我通过使用部分专业化的辅助类来解决这个问题。
但是为什么上面的例子会导致这种奇怪的行为呢?为什么编译器不想使用 const 版本有效且匹配更好的非 const 版本?