获取编译器错误尝试调用模板类的模板方法

时间:2019-04-27 10:15:24

标签: c++ c++11 template-meta-programming

这是我第一次尝试模板元编程,但是在此特定实例中是必需的,因为运行时解决方案无法对整个if / else块进行类型检查。我需要将一种类型的向量(例如int32_t)转换为另一种类型的向量(例如int)。我已经使用模板整理了编译时的实现选择,但是无法编写语法。

如果我直接使用main中的模板参数调用VectorCast_impl函数,则它在两种情况下均有效。但是,当我从VectorCast中调用VectorCast_impl时,出现编译器错误(如代码注释所示)。有什么方法可以正确编译VectorCast函数?

我已经为下面的代码注释中列出的VectorCast_impl调用尝试了一些其他语法。作为参考,我在Windows上使用g ++ mingw64,在RHEL6上使用icpc。

#include <type_traits>
#include <vector>
#include <iostream>

template <bool>  // Handle two of the same types
struct VectorCast_impl
{
    template <class Tout, class Tin>
    static std::vector<Tout> Cast(std::vector<Tin>& x)
    {
        std::cout << "Vectors are same\n";
        return x;
    }
};

template <>     // Specialization for different types
struct VectorCast_impl<false>
{
    template <class Tout, class Tin >
    static std::vector<Tout> Cast(std::vector<Tin>& x)
    {
        std::cout << "Vectors are different\n";
        return std::vector<Tout>(x.begin(), x.end());
    }
};

/* This is the desired syntax:
 * std::vector<int> inp{0,1,2};
 * std::vector<double> output = VectorCast<double>(inp);
 *
 * However, I can't get this working yet.  The syntax above is recognized by the compiler
 * but the VectorCast_impl call fails.
 */

template <class Tout, class Tin>
std::vector<Tout> VectorCast(std::vector<Tin>& x)
{
//    return std::vector<Tout>(8,-1); // works, but just a test case (not desired behavior)
//    return VectorCast_impl<std::is_same<Tin, Tout>::value>::Cast(x);  // Compiler error: couldn't deduce template parameter 'Tout'
    return VectorCast_impl<std::is_same<Tin, Tout>::value>::Cast<Tout>(x); // Compiler error: expected pirmary-expression before '>' token
}

typedef int xxxx;
int main()
{
    std::vector<int> vint{0,1,2};
    for (const auto& i: VectorCast_impl<std::is_same<int,xxxx>::value>::Cast<xxxx>(vint))
        std::cout << i << "\n";

    std::vector<double> vd = VectorCast_impl<std::is_same<int,double>::value>::Cast<double>(vint);
    std::cout << vd[1] + 1.23538 << "\n";

    vd = VectorCast<double>(vint);
    std::cout << vd[2] * 3.425 << "\n";
    return 0;
}

1 个答案:

答案 0 :(得分:0)

您需要使用Cast关键字来使template符合条件。问题在于,编译器无法始终在<作为模板参数列表的开始与<作为“较少”运算符之间进行区分。在这种情况下,我们必须给它一个提示。

template <class Tout, class Tin>
std::vector<Tout> VectorCast(std::vector<Tin>& x)
{
    return VectorCast_impl<std::is_same_v<Tin, Tout>>::template Cast<Tout>(x);
}