我有一个模板,其中重载了一个函数,因此它可以处理 std::string
参数和模板实例化时使用的参数类型。这工作正常,除非模板是用 std::string
实例化的,因为这会导致两个具有相同原型(prototype)的成员函数。因此,我选择专门针对这种特殊情况使用该功能。但是,编译器(g++ 4.8.1
和标志 -std=c++0x
)似乎从来没有达到特化实际上覆盖主模板的地步在它似乎意识到它应该使用特化之前,它提示模棱两可的重载。有办法解决这个问题吗?
#include <iostream>
template<class T>
struct A {
std::string foo(std::string s) { return "ptemplate: foo_string"; }
std::string foo(T e) { return "ptemplate: foo_T"; }
};
template<> //Error!
std::string A<std::string>::foo(std::string s) { return "stemplate: foo_string"; }
int main() {
A<int> a; //Ok!
std::cout << a.foo(10) << std::endl;
std::cout << a.foo("10") << std::endl;
//A<std::string> b; //Error!
//std::cout << a.foo("10") << std::endl;
return 0;
}
这会导致编译错误,即使我根本不使用 std::string
实例化(似乎编译器使用 std::string
实例化为一旦它看到特化,并且在它实际处理特化之前,它就会提示模棱两可的过载,特化反过来会“消除歧义”)。
编译器输出:
p.cpp: In instantiation of 'struct A<std::basic_string<char> >':
p.cpp:10:27: required from here
p.cpp:6:14: error: 'std::string A<T>::foo(T) [with T = std::basic_string<char>; std::string = std::basic_string<char>]' cannot be overloaded
std::string foo(T e) { return "ptemplate: foo_T"; }
^
p.cpp:5:14: error: with 'std::string A<T>::foo(std::string) [with T = std::basic_string<char>; std::string = std::basic_string<char>]'
std::string foo(std::string s) { return "ptemplate: foo_string"; }
^
我希望它跳过主模板中 foo()
的实现并使用特化而不考虑主模板 foo()
。是否可以以某种方式完成,也许使用非类型模板参数,或者我是否必须为 std::string
制作一个完全专用的类模板,其中包含它暗示的所有代码重复(我不想使用在这里继承)...其他建议?
最佳答案
当您指定您的成员函数时,您仍然会得到双重歧义声明。您需要专门化结构模板:
template<>
struct A<std::string> {
std::string foo(std::string s) { return "ptemplate: foo_string"; }
};
如果 A
结构有很多成员,也许你可以重构:
template<typename T>
struct Afoo
{
std::string foo(T s) { ... }
std::string foo(std::string s) { ... }
};
template<>
struct Afoo<std::string>
{
std::string foo(std::string s) { ... }
};
template<typename T>
struct A : Afoo<T>
{
//a lot of code
};
关于C++ 模板 : Specialized member function to resolve case of ambiguous overload in primary template,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26650466/