k06a / boolinq

Simplest C++ header-only LINQ template library
MIT License
628 stars 79 forks source link

C++ 20 Windows Build Problem #49

Closed TaeZStkyoht closed 2 years ago

TaeZStkyoht commented 3 years ago

I am using your library. It could be built with C++ 17. But now I've changed my projects to be built with C++ 20 and it gives errors. Simple example error is like that:

int main() {
    vector<int> asd = { 3, 4, 1, -1, 565 };
    for (int b : from(asd).where([](int a) { return a > 3; }).toStdVector())
        cout << b << endl;

    return 0;
}
Severity    Code    Description Project File    Line    Suppression State
Error (active)  E0135   class "boolinq::Linq<std::tuple<boolinq::Linq<std::pair<std::_Vector_const_iterator<std::_Vector_val<std::conditional_t<true, std::_Simple_types<int>, std::_Vec_iter_types<int, size_t, ptrdiff_t, int *, const int *, int &, const int &>>>>, std::_Vector_const_iterator<std::_Vector_val<std::conditional_t<true, std::_Simple_types<int>, std::_Vec_iter_types<int, size_t, ptrdiff_t, int *, const int *, int &, const int &>>>>>, int>, int>, int>" has no member "toStdVector"
k06a commented 3 years ago

@TaeZStkyoht seems really strange that class "boolinq::Linq<***>" has no member "toStdVector", because it has this method:

https://github.com/k06a/boolinq/blob/a362fe917a47a784e818c6b27de29833776eefbc/include/boolinq/boolinq.h#L600-L607

What compiler and version do you use?

TaeZStkyoht commented 3 years ago

I'm using Visual Studio 2019 v16.11.1 on Windows. By the way it's not only toStdVector but also almost all other functions.

RoqueDeicide commented 3 years ago

result_of is deprecated in c++ 20 and needs to be replaced with invoke_result.

k06a commented 2 years ago

@RoqueDeicide @TaeZStkyoht @ZumZoom any ideas how to write universal code using result_of in pre-C++17 and invoke_result_t in C++17+?

RoqueDeicide commented 2 years ago

This code, when put at the top of the file, should allow the rest of the code to stay the same:

#if (defined(_MSC_VER) && _MSVC_LANG >= 202002L) || __cplusplus >= 202002L

namespace std
{
    template<typename _Callable, typename ..._Args>
    using result_of = std::invoke_result<_Callable, _Args...>;
}

#endif
TaeZStkyoht commented 2 years ago

@k06a Are you planning apply these changes, making a new release and updating it on vcpkg?

k06a commented 2 years ago

@TaeZStkyoht applied changes to master branch and added tag 3.0.3. Checking ways to submit new version to vcpkg.

TaeZStkyoht commented 2 years ago

@k06a Ok, thanks a lot.

Mrhyuan commented 2 years ago

It seems the version on vcpkg and conan is still 3.0.2. Any plan to update? Thx.

k06a commented 2 years ago

@Mrhyuan requested cvpkg upgrade here: https://github.com/microsoft/vcpkg/issues/22173

k06a commented 2 years ago

@Mrhyuan done via https://github.com/microsoft/vcpkg/pull/22177

Mrhyuan commented 2 years ago

@Mrhyuan done via microsoft/vcpkg#22177

So fast thank you so much

TaeZStkyoht commented 2 years ago

@k06a Ok "toStdVector" works now but some of them still doesn't work (especially "select"). Did you try your examples on your readme page? They don't work. Now I'm using Visual Studio 2019 16.11.8, _MSC_VER 1929, _MSVC_LANG 202002L. Your defined macro (The result_of was deprecated since C++20, so redefine it using invoke_result) is active because these versions satisfy it.

Your example:

int src[] = { 1,2,3,4,5,6,7,8 };
    auto dst = from(src).where([](int a) { return a % 2 == 1; })      // 1,3,5,7
        .select([](int a) { return a * 2; })           // 2,6,10,14
        .where([](int a) { return a > 2 && a < 12; }) // 6,10
        .toStdVector();

Errors:

image

It still works with C++17 on Windows and any modern C++ version on Linux.

@RoqueDeicide Did you also try your work?

k06a commented 2 years ago

@TaeZStkyoht try to specify lambda return type as int

k06a commented 2 years ago

Sad to hear that. This means our template to get return type is not working as expected.

RoqueDeicide commented 2 years ago

61 Should fix this for good.

TaeZStkyoht commented 2 years ago

@RoqueDeicide nope. It will not be copiled gcc trunk and clang trunk. @k06a use my suggestion. This is the only compatible solution for now. If you decide not to support before C++17 in the future, just remove this definition and use invoke_result instead. Here you can try on GodBolt: https://godbolt.org/z/GhfezTrnb

TaeZStkyoht commented 2 years ago

And lol @RoqueDeicide You just copied my code and created own pull request? You commited 29 mins ago: image

I commited 5 hours ago: image

TaeZStkyoht commented 2 years ago

And after 5 hours try, I found compatible solution: image

RoqueDeicide commented 2 years ago

@TaeZStkyoht, My code is based on "possible implementation" section of result_of article on cppreference.com Please, refrain from baseless accusations.

I'm not sure about compatibility with compilers that hadn't removed result_of as that just makes them not compatible with c++20 standard.

k06a commented 2 years ago

@TaeZStkyoht @RoqueDeicide thanks for the contributions, I will merge both and resolve conflicts 😁👌👍

k06a commented 2 years ago

Merged both, introduced subnamespace priv to avoid collisions incase of using both std and boolinq namespaces!