【问题标题】:Using constexpr method for template parameterization inside struct使用 constexpr 方法在结构内进行模板参数化
【发布时间】:2016-03-31 04:04:44
【问题描述】:

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

假设您有一个结构,其中包含 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 Update 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>;
};

【问题讨论】:

  • 你真的编译了吗?不要依赖智能感知。
  • 试图用error C2975: '_Bits': invalid template argument for 'std::bitset', expected compile-time constant expression编译错误
  • Count() 需要是函数吗?为什么不static constexpr std::size_t Count = 3U;

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


【解决方案1】:

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-07-03
    • 2023-03-16
    • 2020-07-15
    • 2019-08-04
    • 1970-01-01
    相关资源
    最近更新 更多