如何使C++模板类型默认为上一个模板类型

huangapple go评论84阅读模式
英文:

How to make C++ template type to default to previous template type

问题

以下是您要翻译的内容:

有没有办法将第二个模板类型默认为第一个模板参数类型的类型,以消除不必要时指定模板类型的需要?

所以,我有一个从字节数组中弹出值的方法:

    template<class TYPE1, class TYPE2>
    bool pop_value_from_array(TYPE2 &value)
    {
        if (get_array_size() >= sizeof(TYPE1))
        {
            value = static_cast<TYPE2>(*reinterpret_cast<const TYPE1*>(&get_array_pointer()));
            remove_bytes_from_array(sizeof(TYPE1));
            return true;
        }
        return false;
    }

然后我可以这样做:

    uint32_t size;
    if (!pop_value_from_array<uint16_t>(size))
    {
        // 错误处理
    }
    size *= 2;
    uint16_t var2;
    if (!pop_value_from_array<uint16_t>(var2))
    {
        // 错误处理
    }

如果我声明另一个函数:

    template<class TYPE>
    bool pop_value_from_array(TYPE &value)
    {
        if (get_array_size() >= sizeof(TYPE))
        {
            value = *reinterpret_cast<const TYPE*>(&get_array_pointer());
            remove_bytes_from_array(sizeof(TYPE));
            return true;
        }
        return false;
    }

我可以在不需要时摆脱模板规范:

    uint32_t size;
    // 从数组中弹出uint16_t,并存储为uint32_t类型,以确保乘法不会溢出
    if (!pop_value_from_array<uint16_t>(size))
    {
        // 错误处理
    }
    size *= 2;
    uint16_t var2;
    if (!pop_value_from_array(var2))
    {
        // 错误处理
    }

因此,我想摆脱对相同函数的第二个声明。

英文:

Is there any way, to default second template type to the type of the first template argument type, to remove the need of specifying the template types when not needed?

So, I have a method, that pops values from byte array:

    template&lt;class TYPE1, class TYPE2&gt;
    bool pop_value_from_array(TYPE2 &amp;value)
    {
        if(get_array_size() &gt;= sizeof(TYPE1))
        {
            value = static_cast&lt;TYPE2&gt;(*reinterpret_cast&lt;const TYPE1*&gt;(get_array_pointer()));
            remove_bytes_from_array(sizeof(TYPE1));
            return true;
        }
        return false;
    }

And then I can do

    uint32_t size;
    if (!pop_value_from_array&lt;uint16_t&gt;(size))
    {
        // Error handling
    }
    size *= 2;
    uint16_t var2;
    if (!pop_value_from_array&lt;uint16_t&gt;(var2))
    {
        // Error handling
    }

If I declare another function:

    template&lt;class TYPE&gt;
    bool pop_value_from_array(TYPE &amp;value)
    {
        if(get_array_size() &gt;= sizeof(TYPE))
        {
            value = *reinterpret_cast&lt;const TYPE*&gt;(get_array_pointer());
            remove_bytes_from_array(sizeof(TYPE));
            return true;
        }
        return false;
    }

I can get rid of the template specification when not needed:

    uint32_t size;
    // Poping uint16_t from array, and storing to the uint32_t type, so there is no overflow in multiplication
    if (!pop_value_from_array&lt;uint16_t&gt;(size))
    {
        // Error handling
    }
    size *= 2;
    uint16_t var2;
    if (!pop_value_from_array(var2))
    {
        // Error handling
    }

So, I want to get rid of the second declaration of the same function

答案1

得分: 0

Templates parameters can be defaulted:

    template<class TYPE1, class TYPE2=TYPE1>
    bool pop_value_from_array(TYPE2 &value)
// ...

Now this template can be invoked with just one parameter, and the second one gets defaulted in the expected manner.

There are some restrictions on template parameter defaulting. Your C++ textbook should have the complete details.

英文:

Templates parameters can be defaulted:

    template&lt;class TYPE1, class TYPE2=TYPE1&gt;
    bool pop_value_from_array(TYPE2 &amp;value)
// ...

Now this template can be invoked with just one parameter, and the second one gets defaulted in the expected manner.

There are some restrictions on template parameter defaulting. Your C++ textbook should have the complete details.

答案2

得分: 0

你可以将TYPE1默认为某种特殊类型(我在这里使用void),然后检查该类型:

template<class TYPE1 = void, class TYPE2>
bool pop_value_from_array(TYPE2 &value)
{
    using type = std::conditional_t<std::is_same_v<void, TYPE1>, TYPE2, TYPE1>;
    // 现在使用type。
    if (get_array_size() >= sizeof(type))
    {
        value = static_cast<TYPE2>(*reinterpret_cast<const type*>(&get_array_pointer()));
        remove_bytes_from_array(sizeof(type));
        return true;
    }
    return false;
}
英文:

You might default TYPE1 to some special type (I use void here), and then check for that type:

template&lt;class TYPE1 = void, class TYPE2&gt;
bool pop_value_from_array(TYPE2 &amp;value)
{
    using type = std::conditional_t&lt;std::is_same_v&lt;void, TYPE1&gt;, TYPE2, TYPE1&gt;;
    // Now use type.
    if(get_array_size() &gt;= sizeof(type))
    {
        value = static_cast&lt;TYPE2&gt;(*reinterpret_cast&lt;const type*&gt;(get_array_pointer()));
        remove_bytes_from_array(sizeof(type));
        return true;
    }
    return false;
}

huangapple
  • 本文由 发表于 2023年5月10日 19:31:48
  • 转载请务必保留本文链接:https://go.coder-hub.com/76217890.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定