c++ - C++20 compile time retrieve size of a vector - Stack Overflow
I have a question regarding to the compile time retrieving size of a vector
in C++20. Based on C++20 it is possible to create in compile time a vector
or a string
in the scope of a function.
There is the following piece of code
#include <iostream>
#include <vector>
#include <array>
consteval auto copyVecToArray(){
std::vector<int> vec{1,2,3,4,5,6,7};
std::array<int,vec.size()> arr;
std::copy(std::begin(vec),std::end(vec),std::begin(arr));
return arr;
}
int main() {
constexpr auto value = copyVecToArray();
for(auto el : value){
std::cout << el << std::endl;
}
}
Demo which is failed with following compilation error
> <source>:7:28: in 'constexpr' expansion of
> 'vec.std::vector<int>::size()'
> /opt/compiler-explorer/gcc-14.2.0/include/c++/14.2.0/bits/stl_vector.h:993:32:
> error: the value of 'vec' is not usable in a constant expression 993
> | { return size_type(this->_M_impl._M_finish -
> this->_M_impl._M_start); }
> | ~~~~~~^~~~~~~ <source>:6:22: note: 'vec' was not declared 'constexpr'
> 6 | std::vector<int> vec{1,2,3,4,5,6,7};
> | ^~~ <source>:7:28: note: in template argument for type 'long unsigned int'
> 7 | std::array<int,vec.size()> arr;
> | ~~~~~~~~^~ <source>:8:55: error: no matching function for call to 'begin(int&)'
> 8 | std::copy(std::begin(vec),std::end(vec),std::begin(arr));
> |
But if I change a bit the code above and return the size of the vector
from a consteval
function this successfully compiles.
#include <iostream>
#include <vector>
#include <array>
consteval auto getVec(){
std::vector<int> vec{1,2,3,4,5,6,7};
return vec;
}
consteval auto getSize(){
return getVec().size();
}
consteval auto copyVecToArray(){
std::array<int,getVec().size()> arr;
auto vec = getVec();
std::copy(std::begin(vec),std::end(vec),std::begin(arr));
return arr;
}
int main() {
constexpr auto value = copyVecToArray();
for(auto el : value){
std::cout << el << std::endl;
}
}
My question is why using consteval
function to retrieve size is ok and not using directly the std::vector::size()
method.
Demo 2
I have a question regarding to the compile time retrieving size of a vector
in C++20. Based on C++20 it is possible to create in compile time a vector
or a string
in the scope of a function.
There is the following piece of code
#include <iostream>
#include <vector>
#include <array>
consteval auto copyVecToArray(){
std::vector<int> vec{1,2,3,4,5,6,7};
std::array<int,vec.size()> arr;
std::copy(std::begin(vec),std::end(vec),std::begin(arr));
return arr;
}
int main() {
constexpr auto value = copyVecToArray();
for(auto el : value){
std::cout << el << std::endl;
}
}
Demo which is failed with following compilation error
> <source>:7:28: in 'constexpr' expansion of
> 'vec.std::vector<int>::size()'
> /opt/compiler-explorer/gcc-14.2.0/include/c++/14.2.0/bits/stl_vector.h:993:32:
> error: the value of 'vec' is not usable in a constant expression 993
> | { return size_type(this->_M_impl._M_finish -
> this->_M_impl._M_start); }
> | ~~~~~~^~~~~~~ <source>:6:22: note: 'vec' was not declared 'constexpr'
> 6 | std::vector<int> vec{1,2,3,4,5,6,7};
> | ^~~ <source>:7:28: note: in template argument for type 'long unsigned int'
> 7 | std::array<int,vec.size()> arr;
> | ~~~~~~~~^~ <source>:8:55: error: no matching function for call to 'begin(int&)'
> 8 | std::copy(std::begin(vec),std::end(vec),std::begin(arr));
> |
But if I change a bit the code above and return the size of the vector
from a consteval
function this successfully compiles.
#include <iostream>
#include <vector>
#include <array>
consteval auto getVec(){
std::vector<int> vec{1,2,3,4,5,6,7};
return vec;
}
consteval auto getSize(){
return getVec().size();
}
consteval auto copyVecToArray(){
std::array<int,getVec().size()> arr;
auto vec = getVec();
std::copy(std::begin(vec),std::end(vec),std::begin(arr));
return arr;
}
int main() {
constexpr auto value = copyVecToArray();
for(auto el : value){
std::cout << el << std::endl;
}
}
My question is why using consteval
function to retrieve size is ok and not using directly the std::vector::size()
method.
Demo 2
Share Improve this question edited yesterday Some programmer dude 409k35 gold badges413 silver badges642 bronze badges asked yesterday getsoublgetsoubl 94512 silver badges29 bronze badges 1- fyi, the way people do this is using a lambda to get around exactly that. example with lambda, i am guessing that the rvalues are constexpr but once it becomes an lvalue it is no-longer constexpr, also see Youtube Understanding The constexpr 2-Step - Jason Turner - C++ on Sea 2024 for a neater way to do this without invoking the lambda twice, useful for complex lambdas. – Ahmed AEK Commented yesterday
1 Answer
Reset to default 2Local variables even in consteval
functions are not constant expressions because they are able to depend on the values of the function’s parameters. It breaks the type system to let them be such. Nor can you work around this (even when the parameter values aren’t needed) by declaring the std::vector
constexpr
, since only empty vectors can be complete constant expressions (for deeply technical reasons). Thus the compute-twice trick.
- 纳德拉:微软所有软件将转向包年订户模式
- 苹果兜售没用软件脸不红心不跳
- 有事请烧纸!清明祭奠已死的平板电脑
- visual studio 2017 - C++ build errors with wxWidgets 3.1.2 and Connect method - Stack Overflow
- swift - Content inside .sheet() being infinitely called - Stack Overflow
- How to solve the error in "Plugin [id: 'org.jetbrains.kotlin.android', version: '1.9.0'
- ST_CONTAINS() giving FALSE even if Point lies within polygon. google-bigquery - Stack Overflow
- node.js - Cors errors S3 Upload node - Stack Overflow
- ruby on rails - ActiveRecord not getting id after save - Stack Overflow
- azure managed identity - Durable Function error "This request is not authorized to perform this operation" - S
- c++ - inlining failed in call to ‘always_inline’ ‘vld1q_u16’ - cross compiling Node.js for armv6 - Stack Overflow
- c# - Unity build error for Android when use CMake with Ninja on Mac - Stack Overflow
- Optional parentheses for C variadic macro (i.e. both function-like and object-like) - Stack Overflow
- ace - Does JSONEditor have a default function to get the JSON block from the cursor position? - Stack Overflow
- c++ - Member of struct constructed twice in custom constructor? - Stack Overflow
- ios - Persist overlay view in the detail side of NavigationSplitView - Stack Overflow
- postgresql - Custom stopwords dictionary in Postgres hosted on GCP Cloud SQL - Stack Overflow