C++ 模板部分专门化:如何避免代码重复?
当模板完全专用化时,不需要复制成员函数。例如,在下面的代码中,C++ 模板部分专门化:如何避免代码重复?,c++,templates,partial-specialization,C++,Templates,Partial Specialization,当模板完全专用化时,不需要复制成员函数。例如,在下面的代码中,foo()只编写一次 #include <iostream> template<int M> class B { public: void foo(); private: void header(); }; template<int M> void B<M>::foo() {
foo()
只编写一次
#include <iostream>
template<int M>
class B
{
public:
void foo();
private:
void header();
};
template<int M>
void
B<M>::foo()
{
// specialized code:
header();
// generic code:
std::cout << "M = " << M << std::endl;
}
template<int M>
void
B<M>::header()
{
std::cout << "general foo()" << std::endl;
}
template<>
void
B<2>::header()
{
std::cout << "special foo()" << std::endl;
}
#包括
模板
B类
{
公众:
void foo();
私人:
空标题();
};
模板
无效的
B::foo()
{
//专用代码:
标题();
//通用代码:
std::cout您可以将标题
移动到一个单独的类中,并且只能部分专门化这个类:
#include <iostream>
template <int M, int N>
struct Header
{
static void header()
{
std::cout << "general foo()" << std::endl;
}
};
template <int N>
struct Header<2, N>
{
static void header()
{
std::cout << "special foo()" << std::endl;
}
};
template<int M, int N>
struct A
{
void foo();
};
template<int M, int N>
void
A<M, N>::foo()
{
Header<M,N>::header();
std::cout << "M = " << M << ", N = " << N << std::endl;
}
int main()
{
A<1,1> a11;
a11.foo();
A<2,5> a25;
a25.foo();
}
在这种情况下,我将创建一个不知道模板参数“N”的基类:
#include <iostream>
template<int M>
class ABase
{
protected:
void header();
};
template<int M>
void
ABase<M>::header()
{
std::cout << "general header()" << std::endl;
}
template<>
void ABase<2>::header()
{
std::cout << "special header()" << std::endl;
}
template<int M, int N>
class A : private ABase<M>
{
public:
void foo();
};
template<int M, int N>
void
A<M, N>::foo()
{
// specialized code:
this->header();
// generic code:
std::cout << "M = " << M << ", N = " << N << std::endl;
}
int main()
{
A<1,0> a1;
a1.foo();
A<2,0> a2;
a2.foo();
}
#包括
模板
等级降级
{
受保护的:
空标题();
};
模板
无效的
ABase::header()
{
std::cout使用标签分派的强制回答:
您可以创建一个重载的helper函数;一个在M==2
情况下被调用,另一个在M!=2
情况下被调用。这允许您避免创建模板化的基类。我们需要做的就是将条件M==2
转换为一个类型,我们将使用std::true\u type
和std::false\u type来完成代码>来自
感谢所有提供答案的人
遵循另一个链接提供的链接并继续沿着另一个链接进行操作将导致解决方案,该解决方案使用std::enable_if
而不是模板部分专门化
针对手头的问题实施it可以提供:
#include <iostream>
template<int M, int N>
class A
{
public:
void foo();
private:
template<int MM = M, int NN = N,
typename std::enable_if<MM != 2>::type* = nullptr>
void header()
{
std::cout << "general foo()" << std::endl;
}
template<int MM = M, int NN = N,
typename std::enable_if<MM == 2>::type* = nullptr>
void header()
{
std::cout << "special foo()" << std::endl;
}
};
template<int M, int N>
void
A<M, N>::foo()
{
// specialized code:
header();
// generic code:
std::cout << "M = " << M << ", N = " << N << std::endl;
}
#包括
模板
甲级
{
公众:
void foo();
私人:
模板
空标题()
{
std::难道我不知道在不专门化整个类的情况下,可以专门化类模板的方法。相关:
#include <iostream>
template<int M>
class ABase
{
protected:
void header();
};
template<int M>
void
ABase<M>::header()
{
std::cout << "general header()" << std::endl;
}
template<>
void ABase<2>::header()
{
std::cout << "special header()" << std::endl;
}
template<int M, int N>
class A : private ABase<M>
{
public:
void foo();
};
template<int M, int N>
void
A<M, N>::foo()
{
// specialized code:
this->header();
// generic code:
std::cout << "M = " << M << ", N = " << N << std::endl;
}
int main()
{
A<1,0> a1;
a1.foo();
A<2,0> a2;
a2.foo();
}
template<int M, int N>
class A
{
public:
void foo();
private:
void header();
void foo_helper(std::true_type); // for M == 2 case
void foo_helper(std::false_type); // for M != 2 case
};
template<int I>
struct is_2 : std::false_type{};
template<>
struct is_2<2> : std::true_type{};
template<int M, int N>
void
A<M, N>::foo()
{
foo_helper(typename is_2<M>::type{});
// specialized code:
header();
// generic code:
std::cout << "M = " << M << ", N = " << N << std::endl;
}
template<int M, int N>
void
A<M, N>::foo_helper(std::true_type)
{
std::cout << "Specialized code for M==2 case\n";
}
template<int M, int N>
void
A<M,N>::foo_helper(std::false_type)
{
std::cout << "M!=2 case\n";
}
// inside void foo()
foo_helper(std::integral_constant<int, M>());
template<typename T>
void foo_helper(T) // for M != 2 case
{
std::cout << "M!=2 case\n";
}
void foo_helper(std::integral_constant<int, 2>) // for M == 2 case
{
std::cout << "Specialized code for M==2 case\n";
}
#include <iostream>
template<int M, int N>
class A
{
public:
void foo();
private:
template<int MM = M, int NN = N,
typename std::enable_if<MM != 2>::type* = nullptr>
void header()
{
std::cout << "general foo()" << std::endl;
}
template<int MM = M, int NN = N,
typename std::enable_if<MM == 2>::type* = nullptr>
void header()
{
std::cout << "special foo()" << std::endl;
}
};
template<int M, int N>
void
A<M, N>::foo()
{
// specialized code:
header();
// generic code:
std::cout << "M = " << M << ", N = " << N << std::endl;
}