使用constexpr方法在struct中进行模板参数化

时间:2016-03-31 04:04:45

标签: c++ templates visual-studio-2015 constexpr

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

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

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成员变量中,并从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>;
};

1 个答案:

答案 0 :(得分:2)

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