samedi 27 avril 2019

Getting compiler errors with my implementation selection

This is my first foray into template meta-programming but it's required in this particular instance because a runtime solution fails to type check the whole if/else block. I need to convert a vector of one type (e.g. int32_t) to a vector of another type (e.g. int). I've put together a compile time implementation selection using templates but can't get the syntax write.

If I directly call my VectorCast_impl functions with template parameters from main, it works in both instances. However when I call VectorCast_impl from within VectorCast I'm getting compiler errors (shown in the code comments). Is there any way to get the VectorCast function compiled without errors?

I've tried a few additional syntaxes for the VectorCast_impl calls that are listed in the code comments below. For reference I'm using g++ mingw64 on windows and icpc on RHEL6.

#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;
}

Aucun commentaire:

Enregistrer un commentaire