Calling constexpr function for bitset template parameter

人走茶凉 提交于 2019-12-25 06:47:56

问题


I'm trying to type alias the std::bitset class where the template parameter N is calculated using a constexpr function. However, this approach seems to be running into a wall.

The code currently looks like this:

static constexpr std::size_t ComponentCount() noexcept {
    return 3U;
}

static constexpr std::size_t TagCount() noexcept {
    return 5U;
}

using Bitset = std::bitset<ComponentCount() + TagCount()>;

And the error I'm receiving is as follows:

1>error C2975: '_Bits': invalid template argument for 'std::bitset', expected compile-time constant expression
1>  note: see declaration of '_Bits'

Thanks for your help.


回答1:


As indicated in the comments by @MattWeber, using the current webcompiler.cloudapp.net with compiler version 19.00.23720.0 (built 20 January 2016) this small test program using your code

int main()
{
   cout << Bitset{}.size() << "\n";
}

does output 8. So just grab the latest Visual Studio and check the compiler version (if it's greater than 19.00.23720.0 it should work).




回答2:


As things turned out, I didn't include enough context in my original question. The problem ended up being a little more subtle.

Here's a more accurate representation of how my code looked:

template
<
    typename ComponentList,
    typename TagList,
    typename SignatureList
>
struct Settings {
    // ...

    static constexpr std::size_t ComponentCount() noexcept {
        return 3U;
    }

    static constexpr std::size_t TagCount() noexcept {
        return 5U;
    }

    // ...

    using Bitset = std::bitset<ComponentCount() + TagCount()>;

    // ...
};

This approach seemed okay to me, and didn't provide me with any compiler warnings or anything. Just the compiler error mentioned in the original question.

However, when I simplified the problem further in an attempt to more accurately isolate the problem, I ended up with this:

struct Settings {
    static constexpr std::size_t ComponentCount() noexcept {
        return 3U;
    }

    static constexpr std::size_t TagCount() noexcept {
        return 5U;
    }

    using Bitset = std::bitset<ComponentCount() + TagCount()>;
};

After doing this simplification (or more specifically, after removing the template parameters), VS2015 found the the error function call must have a constant value in a constant expression on both of the ComponentCount() and TagCount() function calls, and highlighted them in red. Apparently the compiler is unable to view static constexpr functions that are contained within the same struct as constant expressions? Weird. It might be trying to do the type aliasing before defining the const expressions.

The solution for the templated struct was as follows:

using ThisType = Settings<ComponentList, TagList, SignatureList>;

// ...

using Bitset = std::bitset<ThisType::ComponentCount() + ThisType::TagCount()>;

However, this approach doesn't work for the non-templated struct. See my other StackOverflow post for different approaches in that case.



来源:https://stackoverflow.com/questions/36256242/calling-constexpr-function-for-bitset-template-parameter

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