I have a lambda that ignores its int parameter and always returns a constant.
If I mark it consteval, compilation fails because.
The compiler complains about invoking the consteval lambda with a non-const parameter.
But what does the parameter has to do with the lambda?
From CompilerExplorer:
source:3:16: error: the value of 'i' is not usable in a constant
expression
5 | lambda(i);
void bar (auto lambda, int start, int end) {
for (int i=start; i<end; ++i) {
lambda(i);
}
}
int main( )
{
auto foo = [] (int) consteval { return 2;};
bar(foo, 1, 9);
return 0;
}
One way to solve this(and the simplest) is to change the parameter type of the lambda to int& so that it doesn't need to read the value, as shown below:
int main( )
{//-------------------v------------------------->reference added
auto foo = [] (int&) consteval { return 2;};
bar(foo, 1, 9);
return 0;
}
Working demo
Here is another contrived example that has similar behavior:
template<typename T>
consteval int func(const T) //note NO REFERENCE HERE
{
return std::is_integral<T>::value;;
}
template<typename T>
//-----------------------v----->note the reference here
consteval int bar(const T&)
{
return std::is_integral<T>::value;;
}
int main()
{
int p = 2;
//constexpr int d = func(p); //doesn't work
constexpr int f = bar(p); //works
}
Contrived example demo
You can also add an explicit check. Not the most elegant solution, but yeah:
#include <type_traits>
void bar(auto lambda, int start, int end) {
for (int i = start; i < end; ++i) {
if constexpr (std::is_invocable_v<decltype(lambda)>) {
lambda();
} else {
lambda(i);
}
}
}
int main() {
bar([] () consteval { return 2; }, 1, 9);
bar([](int) { return 2; }, 1, 9);
return 0;
}
Another way would be to make bar an immediate function. Altough, the usability of an immediate function returning void is rather limited.
consteval void bar(auto lambda, int start, int end) {
for (int i = start; i < end; ++i) {
lambda(i);
}
}
int main() {
bar([](int) consteval { return 2; }, 1, 9);
}
Related
I'm looking for a generic way of measuring a functions timing like Here, but for c++.
My main goal is to not have cluttered code like this piece everywhere:
auto t1 = std::chrono::high_resolution_clock::now();
function(arg1, arg2);
auto t2 = std::chrono::high_resolution_clock::now();
auto tDur = std::chrono::duration_cast<std::chrono::microseconds>(t2 - t1);
But rather have a nice wrapper around the function.
What I got so far is:
timing.hpp:
#pragma once
#include <chrono>
#include <functional>
template <typename Tret, typename Tin1, typename Tin2> unsigned int getDuration(std::function<Tret(Tin1, Tin2)> function, Tin1 arg1, Tin2 arg2, Tret& retValue)
{
auto t1 = std::chrono::high_resolution_clock::now();
retValue = function(arg1, arg2);
auto t2 = std::chrono::high_resolution_clock::now();
auto tDur = std::chrono::duration_cast<std::chrono::microseconds>(t2 - t1);
return tDur.count();
}
main.cpp:
#include "timing.hpp"
#include "matrix.hpp"
constexpr int G_MATRIXSIZE = 2000;
int main(int argc, char** argv)
{
CMatrix<double> myMatrix(G_MATRIXSIZE);
bool ret;
// this call is quite ugly
std::function<bool(int, std::vector<double>)> fillRow = std::bind(&CMatrix<double>::fillRow, &myMatrix, 0, fillVec);
auto duration = getDuration(fillRow, 5, fillVec, ret );
std::cout << "duration(ms): " << duration << std::endl;
}
in case sb wants to test the code, matrix.hpp:
#pragma once
#include <iostream>
#include <string>
#include <sstream>
#include <vector>
template<typename T> class CMatrix {
public:
// ctor
CMatrix(int size) :
m_size(size)
{
m_matrixData = new std::vector<std::vector<T>>;
createUnityMatrix();
}
// dtor
~CMatrix()
{
std::cout << "Destructor of CMatrix called" << std::endl;
delete m_matrixData;
}
// print to std::out
void printMatrix()
{
std::ostringstream oss;
for (int i = 0; i < m_size; i++)
{
for (int j = 0; j < m_size; j++)
{
oss << m_matrixData->at(i).at(j) << ";";
}
oss << "\n";
}
std::cout << oss.str() << std::endl;
}
bool fillRow(int index, std::vector<T> row)
{
// checks
if (!indexValid(index))
{
return false;
}
if (row.size() != m_size)
{
return false;
}
// data replacement
for (int j = 0; j < m_size; j++)
{
m_matrixData->at(index).at(j) = row.at(j);
}
return true;
}
bool fillColumn(int index, std::vector<T> column)
{
// checks
if (!indexValid(index))
{
return false;
}
if (column.size() != m_size)
{
return false;
}
// data replacement
for (int j = 0; j < m_size; j++)
{
m_matrixData->at(index).at(j) = column.at(j);
}
return true;
}
private:
// variables
std::vector<std::vector<T>>* m_matrixData;
int m_size;
bool indexValid(int index)
{
if (index + 1 > m_size)
{
return false;
}
return true;
}
// functions
void createUnityMatrix()
{
for (int i = 0; i < m_size; i++)
{
std::vector<T> _vector;
for (int j = 0; j < m_size; j++)
{
if (i == j)
{
_vector.push_back(1);
}
else
{
_vector.push_back(0);
}
}
m_matrixData->push_back(_vector);
}
}
};
The thing is, this code is still quite ugly due to the std::function usage. Is there a better and/or simpler option ?
(+ also I'm sure I messed sth up with the std::bind, I think I need to use std::placeholders since I want to set the arguments later on.)
// edit, correct use of placeholder in main:
std::function<bool(int, std::vector<double>)> fillRow = std::bind(&CMatrix<double>::fillRow, &myMatrix, std::placeholders::_1, std::placeholders::_2);
auto duration = getDuration(fillRow, 18, fillVec, ret );
You can utilize RAII to implement a timer that records the execution time of a code block and a template function that wraps the function you would like to execute with the timer.
#include<string>
#include<chrono>
#include <unistd.h>
struct Timer
{
std::string fn, title;
std::chrono::time_point<std::chrono::steady_clock> start;
Timer(std::string fn, std::string title)
: fn(std::move(fn)), title(std::move(title)), start(std::chrono::steady_clock::now())
{
}
~Timer()
{
const auto elapsed =
std::chrono::duration_cast<std::chrono::microseconds>(std::chrono::steady_clock::now() - start).count();
printf("%s: function=%s; elasepd=%f ms\n", title.c_str(), fn.c_str(), elapsed / 1000.0);
}
};
#ifndef ENABLE_BENCHMARK
static constexpr inline void dummy_fn() { }
#define START_BENCHMARK_TIMER(...) dummy_fn()
#else
#define START_BENCHMARK_TIMER(title) bench::Timer timer(__FUNCTION__, title)
#endif
template<typename F, typename ...Args>
auto time_fn(F&& fn, Args&&... args) {
START_BENCHMARK_TIMER("wrapped fn");
return fn(std::forward<Args>(args)...);
}
int foo(int i) {
usleep(70000);
return i;
}
int main()
{
printf("%d\n", time_fn(foo, 3));
}
stdout:
wrapped fn: function=time_fn; elasepd=71.785000 ms
3
General Idea:
time_fn is a simple template function that calls START_BENCHMARK_TIMER and calls fn with the provided arguments
START_BENCHMARK_TIMER then creates a Timer object. It will record the current time in start. Do note that __FUNCTION__ will be replaced with the function that was called.
When the
provided fn returns or throws an exception, the Timer object from (1) will be destroyed and the destructor will be called. The destructor will then calculate the time difference between the current time and the recorded start time and prints it to stdout
Note:
Even though declaring start and end in time_fn instead of the RAII timer will work, having an RAII timer will allow you to cleanly handle the situation when fn throws an exception
If you are on c++11, you will need to change time_fn declaration to typename std::result_of<F &&(Args &&...)>::type time_fn(F&& fn, Args&&... args).
Edit: Updated the response to include a wrapper function approach.
typedef void (*void_proc)(void* parameter);
void* parallel_init(void* dummy, int core_number);
int parallel_addtask(void* parallel_monitor, void_proc process, void *parameter);
int parallel_waittask(void* parallel_monitor, int task_id);
int parallel_uninit(void* parallel_monitor);
struct parallel_parameter {
int end;
int begin;
};
void process(void* parameter) {
auto p = reinterpret_cast<parallel_parameter*>(parameter);
// ur_function_name(p->begin, p-end);
}
above is a parallel library(c style) which i woule like to use. every time u call it, u should define a specific struct parameter, it is so annoying that i want implement a template function to mitigate the call steps and i try some kinds of methods to achieve this but failed.
template<typename _function, typename... _parameter>
int parallel_executor(_function&& function, _parameter&&... parameter) {
auto res = 0;
parallel_parameter p[8]{0};
auto body = [](void* para) -> void {
auto p = reinterpret_cast<parallel_parameter*>(para);
function(p->begin, p->end, std::forward<_parameter>(parameter)...)
};
auto parallel_handle = parallel_init(nullptr, 8);
do {
for (int i = 0;i < 8; ++i) {
res = parallel_addtask(parallel_handle, body, static_cast<void*>(&p[i]));
if (res != 0) break;
}
for (int i = 0; i < 8; ++i) {
res = parallel_waittask(parallel_handle, i);
if (res != 0) break;
}
} while (false);
parallel_uninit(parallel_handle);
return res;
}
this call is just simple to show my dilemma, when i use the parallel_executor, it turns out sessioncannot be accessed, because i am not specific the capture style, but when i change the body into below style, the parallel_addtask will not accept body function.
auto body = [&](void* para) -> void {
auto p = reinterpret_cast<parallel_parameter*>(para);
function(p->begin, p->end, std::forward<_parameter>(parameter)...)
};
and now i am in this awkward position for a while. below is the call style which i prefered.
auto ret = parallel_executor(
[](int begin, int end, int parameter_1, int parameter_2) {
std::cout << begin << " ==> " << end << " ==> " << parameter_1 << std::endl;
},
100, // parameter_1
200 // parameter_2
);
regarding the issue, i hope I have made myself clear. any suggestion is appreciated.
Wrapper might look like:
class ParrallelWrapper
{
public:
ParrallelWrapper(int core_number) :
parallel_monitor(parallel_init(nullptr, core_number))
{}
ParrallelWrapper(const ParrallelWrapper&) = delete;
ParrallelWrapper& operator= (const ParrallelWrapper&) = delete;
~ParrallelWrapper() { parallel_uninit(parallel_monitor); }
int AddTask(std::function<void()> f) {
auto run_function = *[](void* f){
(*reinterpret_cast<std::function<void()>*>(f))();
};
functions.push_back(std::make_unique<std::function<void()>>(f));
return parallel_addtask(parallel_monitor, run_function, functions.back().get());
}
int Wait(int task_id) { return parallel_waittask(parallel_monitor, task_id); }
private:
void* parallel_monitor = nullptr;
// Ensure lifetime, and pointer consistence.
std::vector<std::unique_ptr<std::function<void()>>> functions;
};
Demo
With appropriate blanks for specifying begin, end, and the number of tasks, you can use something like
struct parallel_deleter {
void operator()(void *m) const {parallel_uninit(m);}
};
template<class F,class ...TT>
int parallel_executor(F f,TT &&...tt) {
constexpr auto p=+f; // require captureless
constexpr int n=/*...*/;
std::unique_ptr<void,parallel_deleter> m(parallel_init(nullptr,n));
struct arg {
int begin,end;
std::tuple<TT...> user;
};
std::vector<arg> v(n,{0,0,{tt...}});
for(auto &x : v) {
x.begin=/*...*/;
x.end=/*...*/;
if(const int res=parallel_addtask(m.get(),[](void *v) {
const auto &a=*static_cast<arg*>(v);
std::apply([&a](auto &...aa) {p(a.begin,a.end,aa...);},a.user);
},&x)) return res;
}
for(int i=0;i<n;++i)
if(const int res=parallel_waittask(m.get(),i)) return res;
return parallel_uninit(m.release());
}
This design relies on a captureless lambda being passed (so that p can be used inside the task lambda without capturing anything); if you need to support any callable, Jarod42's solution based on std::function is superior.
For some reason the below code gives me fatal error C1001: Internal compiler error. with MSVC 19.27, but not with Clang. Any idea how to write it so that the static_assert can be done also on MSVC?
template <typename T, int N, typename K, int M>
constexpr int countIdentifersNotInArray(const T(&identifiers)[N], const K(&array)[M]) {
auto find = [&array](const unsigned char value) {
for (const auto& a : array) {
if (a == value) {
return true;
}
}
return false;
};
int count = 0;
for (const auto& value : identifiers) {
if (!find(value)) {
++count;
}
}
return count;
}
constexpr bool testIt() {
return countIdentifersNotInArray({ 0x01, 0x02 }, { 0x01 });
}
int main() {
static_assert(testIt());
return 0;
}
I would like to use this in a an environment where stl is not available, so solutions without that are most interesting.
As the comment has pointed out, this is an MSVC bug and you should definitely report to Microsoft.
By removing multiple lines until it stops crashing the compiler, I believe the cause is the range-for loops. So, since they're arrays with known size, you can workaround with the classic indexed loops:
template <typename T, int N, typename K, int M>
constexpr int countIdentifersNotInArray(const T(&identifiers)[N], const K(&array)[M]) {
auto find = [&array](const auto value) {
for (int i = 0; i < M; i++) {
if (array[i] == value) {
return true;
}
}
return false;
};
int count = 0;
for (int i = 0; i < N; i++) {
if (!find(identifiers[i])) {
++count;
}
}
return count;
}
It works on MSVC.
So I have the following simple snippet:
template <typename T, size_t size>
struct SquareMatrix {
public:
T data[size * size];
constexpr T & operator()(const size_t row, const size_t col) noexcept {
return data[row * size + col];
}
};
constexpr auto generate() {
auto result = SquareMatrix<int, 2>{};
result(0, 0) = 1;
result(1, 0) = 3;
result(0, 1) = 2;
result(1, 1) = 4;
return result;
}
The expected contents of the data array in the SquareMatrix<int, 2> produced by generate() is 1, 2, 3, 4. However...
constexpr auto test = generate();
int main() {
for (size_t i = 0; i < 4; ++i) {
std::cout << test.data[i] << std::endl;
}
return 0;
}
If I compile and run this code using g++ 5.2 and -std=c++14, the result that is printed to the console is, bizarrely, 1032.
If remove the constexpr qualifiers so it executes at runtime, or if I instead write either of the following slight variations:
int main() {
constexpr auto test = generate();
for (size_t i = 0; i < 4; ++i) {
std::cout << test.data[i];
}
return 0;
}
... or ...
constexpr auto generate() {
auto result = SquareMatrix<int, 2>{};
result(0, 0) = 1;
result(0, 1) = 2; // this line and
result(1, 0) = 3; // this line have been swapped
result(1, 1) = 4;
return result;
}
constexpr auto test = generate();
int main() {
for (size_t i = 0; i < 4; ++i) {
std::cout << test.data[i];
}
return 0;
}
... the expected result, 1234, is printed. Additionally, clang++ 3.7.0 prints the expected 1234 in all cases.
Have I hit a g++ bug or am I missing something here?
This looks related to the gcc bug [5 regression] Constant expression factory function initializes std::array with static storage duration strangely and if we try this with gcc head live example it works fine.
The bug report has the following similar example, where the static variable case exhibits a similar issue while the automatic variable case does not:
#include <array>
#include <cassert>
namespace /* anonymous */
{
constexpr auto
make_array(const int val) noexcept
{
std::array<int, 2> result = { { val, 0 } };
return result;
}
// Replacing `constexpr` by `const` doesn't change anything.
constexpr auto numbers_static = make_array(42);
}
int main()
{
const auto numbers_automatic = make_array(42);
assert(numbers_automatic[0] == 42); // okay
assert(numbers_static[0] == 42); // fails
}
I have:
const char kLetters[] = "QWERTYUIOPASDFGHJKLZXCVBNM";
I can call kLetters[n] to obtain the nth letter of the Keyboard alphabet in O(1) time. However I will have to iterate through kLetter (taking O(n) or at least O(log n) ) time for the reverse lookup.
I would like to create a reverse lookup table as a compile-time static lookup table using templates and was wondering if there is a ways of doing this.
EDIT - as mentioned in the comments, a reverse lookup would mean I supply 'E' and get back 2. Also my alphabet example was not the best example, I would like to make no assumptions about the order. For that reason I have change the alphabet to keyboard order.
How about something like this? It lets you specify the range rather than a complete string.
#include <iostream>
template <int Start, int End, int N>
struct lookup {
static_assert(Start != End, "Can't have 0 length lookup table");
enum { value = lookup<Start+(Start < End ? 1:-1),End,N-1>::value };
};
template <int Start, int End>
struct lookup<Start,End,0> {
enum { value = Start };
};
template <int Start, int End, int V, int P=0>
struct reverse_lookup {
static_assert(Start != End, "V isn't in the range Start, End");
static_assert(Start != End || !P, "Can't have 0 length range");
enum { value = reverse_lookup<Start+(Start < End ? 1:-1),End,V,P+1>::value };
};
template <int Start, int End, int P>
struct reverse_lookup<Start,End,Start,P> {
enum { value = P };
};
int main() {
std::cout << char(lookup<'A', 'Z', 3>::value) << std::endl;
std::cout << char(lookup<'Z', 'A', 3>::value) << std::endl;
std::cout << int(reverse_lookup<'A','Z','F'>::value) << std::endl;
}
Alright, after knowing what reverse lookup is, I think you can do this:
const char kLetters[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
int get_index(char letter)
{
return letter - 'A';
}
After all, the letter A is at index 0, B at 1, C at 2... and so on. That gives enough hint.
My O(1) solution.
So far other solutions work for non-arbitrary sequence of letters, and #awoodland solution assumes that the letter whose index is to be obtainted is known at compile time which makes it less useful.
But this solution has attempted to solve both limitations; that is, it should work:
With arbitrary sequence of letters, such as
const char Letters[] = "ZBADCEWFVGHIUXJTKSLYQMROPN";
And the letters may be unknown at compile time. The function that gets the index has this signature:
int Index(char letter);
Here is the complete code which uses a technique described by # David RodrÃguez in his blog:
#include <iostream>
const char Letters[] = "ZBADCEWFVGHIUXJTKSLYQMROPN";
template<char L> int Index();
template<> int Index<'Z'>() { return 0; }
template<> int Index<'B'>() { return 1; }
template<> int Index<'A'>() { return 2; }
template<> int Index<'D'>() { return 3; }
template<> int Index<'C'>() { return 4; }
template<> int Index<'E'>() { return 5; }
template<> int Index<'W'>() { return 6; }
template<> int Index<'F'>() { return 7; }
template<> int Index<'V'>() { return 8; }
template<> int Index<'G'>() { return 9; }
template<> int Index<'H'>() { return 10; }
template<> int Index<'I'>() { return 11; }
template<> int Index<'U'>() { return 12; }
template<> int Index<'X'>() { return 13; }
template<> int Index<'J'>() { return 14; }
template<> int Index<'T'>() { return 15; }
template<> int Index<'K'>() { return 16; }
template<> int Index<'S'>() { return 17; }
template<> int Index<'L'>() { return 18; }
template<> int Index<'Y'>() { return 19; }
template<> int Index<'Q'>() { return 20; }
template<> int Index<'M'>() { return 21; }
template<> int Index<'R'>() { return 22; }
template<> int Index<'O'>() { return 23; }
template<> int Index<'P'>() { return 24; }
template<> int Index<'N'>() { return 25; }
typedef int (*fptr)();
const int limit = 26;
fptr indexLookup[ limit ];
template <char L>
struct init_indexLookup {
static void init( fptr *indexLookup ) {
indexLookup[ L - 'A' ] = &Index<L>;
init_indexLookup<L-1>::init( indexLookup );
}
};
template <>
struct init_indexLookup<'A'> {
static void init( fptr *indexLookup ) {
indexLookup[ 0 ] = &Index<'A'>;
}
};
const int ignore = (init_indexLookup<'Z'>::init(indexLookup),0);
int Index(char letter)
{
return indexLookup[letter-'A']();
}
And here is the test code:
int main()
{
std::cout << Index('A') << std::endl;
std::cout << Index('Z') << std::endl;
std::cout << Index('B') << std::endl;
std::cout << Index('K') << std::endl;
}
Output:
2
0
1
16
Online demo : http://ideone.com/uzE2t
Well, that actually is two function calls: one to Index(), other to from one in the indexLookup. You can easily avoid first function call by writing (ideone):
int main()
{
std::cout << indexLookup['A'-'A']() << std::endl;
std::cout << indexLookup['Z'-'A']() << std::endl;
std::cout << indexLookup['B'-'A']() << std::endl;
std::cout << indexLookup['K'-'A']() << std::endl;
}
That looks cumbersome, but hey, we can make Index() inline:
inline int Index(char letter)
{
return indexLookup[letter-'A']();
}
That looks fine, and most likely now compiler will make it equivalent to one function call!
Simple yet O(1) solution
Wait. I just realized that the whole solution reduces to a lookup table which is initialized as:
const int indexLookup[] = {2,1,4,3,5,7,9,10,11,14,16,18,21,
25,23,24,20,22,17,15,12,8,6,13,19,0};
inline int Index(char letter)
{
return indexLookup[letter-'A'];
}
which looks unbelievably simple!
If you can use Boost and only need compile-time lookups:
using namespace boost::mpl;
typedef vector_c<char, 'A', 'B', 'C', 'D'> Chars;
// lookup by index:
std::cout << at_c<Chars, 1>::type::value << std::endl; // B
// lookup by value:
typedef find<Chars, integral_c<char, 'C'> >::type Iter;
std::cout << Iter::pos::value << std::endl; // 2
This assumes that 'Z' > 'A', but does not assume letters are contiguous. (Though it takes less memory if they are) I was tempted to put in if (numrLetters>26) conditionals so a smart compiler could use addition rather than the tables for ASCII, but then decided I didn't want to slow the code in the case of less-smart compilers.
const char kLetters[] = "ABCDEFGHJJKLMNOPQRSTUVWXYZ";
const int numLetters = sizeof(kLetters);
const char rkLetters['Z'-'A'] = {};
const int numrLetters = sizeof(rkLetters);
struct LetterInit {
LetterInit() {
for(int i=0; i<numLetters; ++i)
rkLetters[kLetters[i]-'A'] = i;
}
}LetterInitInst;
char findChar(int index) {
assert(index>=0 && index<numLetters);
return kLetters[index];
}
int findIndex(char letter) {
assert(letter>='A' && letter<='Z');
return rkLetters[letter-'A'];
}
As there are several solutions given that don't generate a table but still allow compile time lookup, here is another one
constexpr char kLetters[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
constexpr int get(char const x, int const i = 0) {
return kLetters[i] == x ? i : get(x, i + 1);
}
Use at compile time
int x[get('F')];
static_assert(sizeof(x) == sizeof(int[5]), "");
Specifying a character that doesn't exist will result in an error. If you use the function at runtime, you will get undefined behavior if you specify a character that doesn't exist. Proper checking can be added for those cases.
It yields the index of the first character found. No error is given if a character appears twice in the haystack.
If you can use c++0x (tested with gcc 4.5), this works:
#include<initializer_list>
#include<iostream>
#include<map>
constexpr int getLetterNumber(char a){ return std::map<char,int>({{'a',2},{'b',1},{'c',4}})[a]; }
int main(){
const char ch='b';
std::cout<<ch<<": "<<getLetterNumber(ch)<<std::endl;
}
constexpr enforces evaluation at compile-time.
EDIT: that solution is not correct, as pointed out. constexpr does not enfoce compile-time evaluation. This does does the lookup really at compile-time (similar to solutions posted meanwhile).
#include<iostream>
template<char C> int ch2Num();
#define CHR(c,i) template<> int ch2Num<c>(){ return i; }
CHR('a',2); CHR('b',1); /* ... */
#undef CHR
int main(void){
const char ch='b';
std::cout<<ch<<": "<<ch2Num<ch>()<<std::endl;
};