使用 constexpr 方法在结构内部进行模板参数化

Using constexpr method for template parameterization inside struct

这是我发现并描述的问题的延续

假设您有一个结构,其中包含一个 static constexpr 函数和一个 std::bitset 的类型别名(或您希望使用 const 表达式的结果模板化的任何类型),如下所示:

struct ExampleStruct {
    static constexpr std::size_t Count() noexcept {
        return 3U;
    }
    using Bitset = std::bitset<Count()>;
};

Visual Studio 2015 版本 14.0.25029.00 更新 2 RC 以红色突出显示 Count() 调用并生成错误 function call must have a constant value in a constant expression.

如何编译或获得类似的结果?

究竟是什么导致了这里的错误?编译器是否试图在 const 表达式函数之前生成类型别名?

编辑:可以在下面找到为什么这不起作用的解释,但由于没有人提供可能的解决方法,这里是我想出的一些方法:

(1) 使用模板时,存储类型别名到这个类型.

template<typename T>
struct ExampleStruct {
    using ThisType = ExampleStruct<T>;
    static constexpr std::size_t Count() noexcept {
        return 3U;
    }
    using Bitset = std::bitset<ThisType::Count()>;
};

(2) 将 Count() 函数移到结构体之外。

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

struct ExampleStruct {
    using Bitset = std::bitset<Count()>;
};

(3)用constexpr成员变量替换constexpr方法

struct ExampleStruct {
    static constexpr std::size_t Count = 3U;
    using Bitset = std::bitset<Count>;
};

(4) 将值存储在constexpr成员变量中,return这个来自Count()方法。

struct ExampleStruct {
private:
    static constexpr std::size_t m_count = 3U;
public:
    static constexpr std::size_t Count() noexcept {
        return m_count;
    }
    using Bitset = std::bitset<m_count>;
};

您可能已经注意到,如果将一行或两行移到 class 正文之外,错误就会消失。您 运行 遇到的问题是 class 成员函数定义(甚至是内联函数定义)直到 after 整个 class 定义具有被解析;因此,当编译器看到 using Bitset = std::bitset<Count()>; 时,此时 Count 已声明但尚未定义,并且尚未定义的 constexpr 函数不能在常量表达式中使用 -所以你得到了你看到的错误。不幸的是,我不知道对此没有好的解决方案或解决方法。