Recursively unpacking a template pack for a parameter-less function

纵然是瞬间 提交于 2021-01-29 13:36:09

问题


I'm trying to create a struct template with a variadic template type pack, that can deduct the sum of the size of all types passed in.

Below you find a simplified example, in the real-world context, the size computed is used to create further member objects.

template <typename... Types>
struct OverallSize
{
    template <typename FirstType, typename... NextTypes>
    static constexpr size_t sizesum() { return sizeof (FirstType) + sizesum<NextTypes...>(); }
    template <typename LastType>
    static constexpr size_t sizesum() { return sizeof (LastType); }

    static constexpr size_t size = sizesum<Types...>();
};

// Should work e.g. like this
auto s = OverallSize<int, float, char>::size; // s will be 9 on x86-64

I'm used to this recursive parameter unpacking approach when it comes to argument lists and assumed this works as well with argument-less functions and explicit template specification. However I get the following error when compiling with clang

Call to 'sizesum' is ambiguous
...
Candidate function [with FirstType = unsigned long, NextTypes = <>]
Candidate function [with LastType = unsigned long]

So it seems as if the last recursion iteration doesn't work here – not sure why the compiler doesn't simply chose the most obvious choice: The one with only one template type – just as it would happen if there was an actual template argument passed to the function.

So, what do I have to do to make this compile and work as desired?


回答1:


For C++14 you can use SFINAE:

template <
    typename FirstType, 
    typename... NextTypes, 
    std::enable_if_t<sizeof...(NextTypes) >= 1>* = nullptr >
static constexpr size_t sizesum() {
    return sizeof (FirstType) + sizesum<NextTypes...>(); 
}

this template will be considered only if parameters pack has size >= 1.

Demo



来源:https://stackoverflow.com/questions/61369873/recursively-unpacking-a-template-pack-for-a-parameter-less-function

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!