模板专业化是否适用于别名模板?具体来说,以下代码会引发意外错误:
$ cat test01.h
#ifndef TEST01_H
#define TEST01_H
#include <iostream>
#include <typeinfo>
#include <cstdlib>
template <template <typename> class Ops>
double add1(double const & x) {
std::cerr << "Undefined for type: " << typeid(Ops <double>).name() << std::endl;
exit(EXIT_FAILURE);
}
template <typename Real>
struct MyOps {
static Real add(Real const & x,Real const & y) {
return x+y;
}
};
template <typename Real> using MyOpsAlias = MyOps <Real>;
#endif
此外,
$ cat test01.cpp
#include "test01.h"
template <>
double add1 <MyOps> (double const & x) {
return MyOps <double>::add(x,1.);
}
int main() {
std::cout << add1 <MyOps> (2.) << std::endl;
std::cout << add1 <MyOpsAlias> (2.) << std::endl;
}
运行此代码后,我收到了
$ ./test01
3
Undefined for type: 5MyOpsIdE
我预计两个答案都应该返回3,因为MyOpsAlias应该只是MyOps的别名模板。如果重要,我正在使用GCC 4.7.3。
答案 0 :(得分:1)
Johannes Schaub - litb在his answer向my recent question中解释:
别名模板不是模板别名(尽管有些人有意)。
所以这不是一个错误,它是符合标准的行为。
另见标准的段落[temp.alias] 14.5.7 / 2:
[注意:永远不会推断出别名模板名称。 - 结束说明]
答案 1 :(得分:0)
您可以执行以下操作:
namespace detail
{
template <typename T> struct Adder
{
double operator() (double) const {
std::cerr << "Undefined for type: " << typeid(T).name() << std::endl;
exit(EXIT_FAILURE);
}
};
template <typename T> struct Adder<MyOps<T>>
{
double operator() (double x) const {
return MyOps<T>::add(x, 1.);
}
};
}
template <template <typename> class T>
double add1(double const & x) {
return detail::Adder<T<double>>()(x);
}