renestein / Rstein.AsyncCpp

The RStein.AsyncCpp library is a set of types that should be familiar for anyone who knows the Task Parallel Library (TPL) for .NET (C#).
MIT License
31 stars 4 forks source link

Dealing with types without default constructors #15

Closed lawabider closed 3 years ago

lawabider commented 3 years ago

I am trying to deal with winrt::Windows::Storage::StorageFile objects from c++/winrt . I can just wrap this type, but is there anything else I can do? Is there any hope that default constructors won't be a requirement in the future?

Doesn't compile; "no appropriate default constructor available":

        auto  m_folderActionBlock = 
         DataFlowAsyncFactory::CreateActionBlock<winrt::Windows::Storage::StorageFolder>([](const Windows::Storage::StorageFolder& item)-> Tasks::Task<void>
            {
                // auto message = "Final action: " + item + "\n";
                // cout << message;
                // await async operation returning Task.
                co_await Tasks::GetCompletedTask();
                //_processedItems.push_back(item);
            });
renestein commented 3 years ago

You are talking about StorageFile, but your code uses StorageFolder. But the culprit of the problem will be the same. I will look into this. Thanks for bringing this to my attention!

renestein commented 3 years ago

@lawabider I don't think that relaxation of the default ctor requirement will help you. You will then most likely have issues with the copy/move actors etc. But you don't need a wrapper for a class that does not have a default ctor. The solution is very simple - use a pointer to the instance of the StorageFile.

TEST_F(DataFlowTest, Default_Ctor)
  {
    const int EXPECTED_VALUE = 101;
    class WithoutDefaultCtor
    {
      public:
        WithoutDefaultCtor(int i): _i(i)
        {

        }

        int Value() const
        {
          return _i;
        }

      private:
        int _i;
    };

    int processedValue  = 0;

    auto ac2  = DataFlowAsyncFactory::CreateActionBlock<WithoutDefaultCtor*>([&processedValue](WithoutDefaultCtor* const& source)-> Tasks::Task<void>
    {
      co_await Tasks::GetCompletedTask();
      processedValue = source->Value();

    });
    WithoutDefaultCtor wdc1 {EXPECTED_VALUE};
    ac2->Start();
    ac2->AcceptInputAsync(&wdc1);
    ac2->Complete();
    ac2->Completion().Wait();

    ASSERT_EQ(EXPECTED_VALUE, processedValue);
  }