喂!
我想只专注于两种模板类型中的一种。例如。 template <typename A, typename B> class X
应该针对单个函数X<float, sometype>::someFunc()
进行特殊实现。
示例代码:
main.h:
#include <iostream>
template <typename F, typename I>
class B
{
public:
void someFunc()
{
std::cout << "normal" << std::endl;
};
void someFuncNotSpecial()
{
std::cout << "normal" << std::endl;
};
};
template <typename I>
void B<float, I>::someFunc();
main.cpp中:
#include <iostream>
#include "main.h"
using namespace std;
template <typename I>
void B<float, I>::someFunc()
{
cout << "special" << endl;
}
int main(int argc, char *argv[])
{
B<int, int> b1;
b1.someFunc();
b1.someFuncNotSpecial();
B<float, int> b2;
b2.someFunc();
b2.someFuncNotSpecial();
}
class B
的编译失败。这是不是真的,这在C ++中是不可能的?什么是最好的解决方法?
[编辑]
template <float, typename I>
void B<float, I>::someFunc();
导致
main.h:26:错误:'float'不是模板常量参数的有效类型
template <typename I>
void B<float, I>::someFunc();
导致
main.h:27:错误:无效使用不完整类型'B类'
我正在使用gcc。
[编辑]
我不想专门研究整个班级,因为还有其他功能没有专业化。
答案 0 :(得分:18)
您必须提供类模板B
的部分特化:
template <typename I>
class B<float, I>
{
public:
void someFunc();
};
template <typename I>
void B<float, I>::someFunc()
{
...
}
您也可以在专业化中定义someFunc
。
然而,如果你只想专门化一个函数,而不是一个类做。克。
template <typename F, typename I>
void someFunc(F f, I i) { someFuncImpl::act(f, i); }
template <typename F, typename I>
struct someFuncImpl { static void act(F f, I i) { ... } };
// Partial specialization
template <typename I>
struct someFuncImpl<float, I> { static void act(float f, I i) { ... } };
但如果没有这个技巧,你就无法专门化一个功能模板。
答案 1 :(得分:5)
虽然你可以完全专注 类模板的成员函数, 你不能_partially专门化 成员职能。 - Andrei Alexandrescu
部分 Class 专业化由其他海报解释。
但是,您可以使用重载:
template <class T, class U> T fun(U obj); // primary template
template <class U> void Fun<void, U>(U obj); // illegal pertial
// specialization
template <class T> T fun (Window obj); // legal (overloading)
如果你想深入研究这个问题,你可以在A. Alexandrescu的“现代C ++设计”中深入阅读这个问题。
答案 2 :(得分:0)
解决方案1.将所有实现移动到像B_Base这样的基类。然后专注于float来覆盖someFunc。如下所示
template <typename F, typename I>
class B : B_Base<F, I>
{
}
template <typename I>
class B<float, I> : B_Base<flat, I>
{
public:
void someFunc() {....}
};
解决方案2.使用函数重载,将float作为输入或boost :: is_same调度。不幸的是,你的函数 someFunc 没有参数。所以它需要改变界面。
答案 3 :(得分:0)
我认为 C++ 专家 Mayer 为我们提供了一个优雅的功能。缺点是它取决于 GCC 功能。
#include <map>
#include <iostream>
#include <string>
using namespace std;
template<typename... T>
void TemplatePrint(T... args) {
std::cout << __PRETTY_FUNCTION__ << std::endl;
}
int main()
{
map<string, int> arr={{"1", 1}, {"2", 2}, {"3", 3}};
auto itr = arr.find("3");
TemplatePrint<decltype(itr)>(itr);
return 0;
}
GCC 会打印出迭代器的真实 decltype(真实的),即:
void TemplatePrint(T ...) [with T = {std::_Rb_tree_iterator<std::pair<const std::basic_string<char, std::char_traits<char>, std::allocator<char> >, int> >}]