编译器选择专用于数组的预期模板,但随后尝试将数组参数强制转换为指针

时间:2014-04-29 22:42:40

标签: c++ templates

以下代码无法编译,基本上存在以下错误:

variadic_function2.cpp:68:17: note:   template argument deduction/substitution failed:
variadic_function2.cpp:86:53: note:   cannot convert ‘params#0’ (type ‘const char [64]’) to type ‘char*’

第68行是Helper<T[N]>::CopyFrom专门化,因此编译器(g ++ 4.8.1)正在选择正确的模板。然而,神秘地(对我来说),它会尝试将char[64]转换为char *

如果第68行改为

static bool CopyFrom (F f, T arr[N])

static bool CopyFrom (F f, const T arr[N])

然后编译好。

有人可以帮我理解发生了什么吗?


#include <vector>
#include <functional>
#include <cstddef>

template <typename T, typename...  Params>
struct Helper
{
    static size_t Sizeof()
    {
        return sizeof (T) + Helper<Params...>::Sizeof();
    }

    template <typename F>
    static bool CopyFrom (F f, T t, Params... params)
    {
        if (!f (reinterpret_cast<const char*>(&t), sizeof(t)))
            return false;

        return Helper<Params...>::CopyFrom (f, params...);
    }
};


template <typename T>
struct Helper<T>
{
    static size_t Sizeof()
    {
        return sizeof (T);
    }

    template <typename F>
    static bool CopyFrom (F f, T t)
    {
        return f (reinterpret_cast<const char*>(&t), sizeof(T));
    }
};


template <typename T, size_t N, typename...  Params>
struct Helper<T[N], Params...>
{
    static size_t Sizeof()
    {
        return N * sizeof (T) + Helper<Params...>::Sizeof();
    }

    template <typename F>
    static bool CopyFrom (F f, T arr[N], Params... params)
    {
        // if (!f (reinterpret_cast<const char*>(arr), sizeof(arr)))
        //     return false;

        return Helper<Params...>::CopyFrom (f, params...);
    }
};


template <typename T, size_t N>
struct Helper<T[N]>
{
    static size_t Sizeof()
    {
        return N * sizeof (T);
    }

    template <typename F>
    static bool CopyFrom (F f, T arr[N])
    {
        return f (reinterpret_cast<const char*>(arr), sizeof(arr));
    }
};


template <typename... Params>
size_t GetSizeof (const Params&... params)
{
    return Helper<Params...>::Sizeof();
}


template <typename F, typename... Params>
bool CopyFrom (F f, const Params&... params)
{
    return Helper<Params...>::CopyFrom (f, params...);
}


struct UnitTestFixture
{
    bool Read (const char* buf, size_t bufLen)
    {
        m_calltrace.push_back (bufLen);
        return true;
    }

    void Reset()
    {
        m_calltrace.clear();
    }

    std::vector<size_t> m_calltrace;
};


int main()
{
    UnitTestFixture utf;
    char buf[64];
    CopyFrom (std::bind(&UnitTestFixture::Read, &utf, std::placeholders::_1, std::placeholders::_2), buf);
}

1 个答案:

答案 0 :(得分:1)

template <typename F, typename... Params>
bool CopyFrom (F f, const Params&... params)
{
    return Helper<Params...>::CopyFrom (f, params...);
}

当你传递char[64]时,params...将是const char (&) [64],它会衰减到const char*,无法传递给期望{{1}的函数}}。删除char*并编译(至少使用gcc)。

此外,const将无法执行您期望的操作(它将返回sizeof(arr),而不是sizeof char*)。通过使用sizeof char[64]代替,很容易解决这个问题。