Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
288 views
in Technique[技术] by (71.8m points)

c++ - Why is a constexpr function on a reference not constexpr?

Consider the following function:

template <size_t S1, size_t S2>
auto concatenate(std::array<uint8_t, S1> &data1, std::array<uint8_t, S2> &data2) {
    std::array<uint8_t, data1.size() + data2.size()> result;

    auto iter = std::copy(data1.begin(), data1.end(), result.begin());
    std::copy(data2.begin(), data2.end(), iter);

    return result;
}

int main()
{
    std::array<uint8_t, 1> data1{ 0x00 };
    std::array<uint8_t, 1> data2{ 0xFF };

    auto result = concatenate(data1, data2);
    return 0;
}

When compiled using clang 6.0, using -std=c++17, this function does not compile, because the size member function on the array is not constexpr due to it being a reference. The error message is this:

error: non-type template argument is not a constant expression

When the parameters are not references, the code works as expected.

I wonder why this would be, as the size() actually returns a template parameter, it could hardly be any more const. Whether the parameter is or is not a reference shouldn't make a difference.

I know I could of course use the S1 and S2 template parameters, the function is merely a short illustration of the problem.

Is there anything in the standard? I was very surprised to get a compile error out of this.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Because you have evaluated a reference. From [expr.const]/4:

An expression e is a core constant expression unless the evaluation of e, following the rules of the abstract machine, would evaluate one of the following expressions:

  • ...
  • an id-expression that refers to a variable or data member of reference type unless the reference has a preceding initialization and either
    • it is usable in constant expressions or
    • its lifetime began within the evaluation of e;
  • ...

Your reference parameter has no preceding initialization, so it cannot be used in a constant expression.

You can simply use S1 + S2 instead here.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...