模板专门化是否适用于别名模板?

时间:2014-04-09 01:50:02

标签: templates c++11

模板专业化是否适用于别名模板?具体来说,以下代码会引发意外错误:

$ 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。

2 个答案:

答案 0 :(得分:1)

Johannes Schaub - litbhis answermy 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);
}