@Colin It is just an example of chat. Firstly, I tried to fix the compilation error with Composer 2. Attempt 1 - error, Attempt 2 - error. Attempt 3 - Composer 2 returns to the initial variant. Fiasko! After that, I switched to Composer 1.5 and it resolve this problem from the first attempt. It does an elementary error.
```cpp
C:/Projects/ESP-IDF/SigmaTransfer/main/testSuiteFlow.cpp:189:22: error: cannot ‘dynamic_cast’ ‘transport’ (of type ‘class Sigma::NonOwningRefSigma::Transfer::ITransport’) to type ‘class Sigma::Transfer::ZeroTransport*’ (source is not a pointer)
Inspecting the code and NonOwningRef to fix the dynamic_cast error.
Casting the underlying pointer: transport is NonOwningRef, not ITransport*. dynamic_cast requires a pointer or reference to a polymorphic type. Using transport.get() (same pattern as elsewhere in the codebase for owned transport pointers).
testSuiteFlow.cpp
+1
-1
auto zTransport = dynamic_cast<ZeroTransport*>(transport);
auto *zTransport = dynamic_cast<ZeroTransport *>(transport.get());
if (zTransport == nullptr) {
Here’s what was wrong and what we changed.
Cause: transport is a Sigma::NonOwningRef, not an ITransport*. dynamic_cast only works on pointers or references to polymorphic types, so casting the wrapper itself is invalid.
Fix: Cast the stored pointer, which NonOwningRef exposes with .get() (same idea as std::unique_ptr / std::shared_ptr):
auto *zTransport = dynamic_cast<ZeroTransport *>(transport.get());
After this change, the compiler should accept it. If your environment doesn’t have idf.py on PATH, run a full build in your usual ESP-IDF shell to confirm.
ESP-IDF Build (1046-1054)
testSuiteFlow.cpp
+1
-1
auto *zTransport = dynamic_cast<ZeroTransport *>(transport.get());
auto *zTransport = dynamic_cast<ZeroTransport *>(transport.Get());
if (zTransport == nullptr) {
Sigma::NonOwningRef exposes the raw pointer via Get() (PascalCase), not get().
Updated line:
auto *zTransport = dynamic_cast<ZeroTransport *>(transport.Get());
Rebuild in your ESP-IDF environment; that should clear the error. If the IDE still shows a dynamic_cast warning, it’s often clangd without the same flags as the IDF build—trust the full idf.py build result.
ESP-IDF Build (1046-1054)
Get() returns an ITransport&, not an ITransport*. dynamic_cast to a pointer requires a pointer — use the address of the reference:
testSuiteFlow.cpp
+1
-1
auto *zTransport = dynamic_cast<ZeroTransport *>(transport.Get());
auto *zTransport = dynamic_cast<ZeroTransport >(&transport.Get());
if (zTransport == nullptr) {
What was wrong: NonOwningRef::Get() gives you an ITransport&, not a pointer. dynamic_cast to ZeroTransport needs a pointer (or a reference with a different cast form).
Change: take the address so the source is an ITransport*:
auto *zTransport = dynamic_cast<ZeroTransport *>(&transport.Get());
ITransport is polymorphic (virtual destructor and methods), so this downcast is valid. Rebuild to confirm.
ESP-IDF Build (1046-1054)
Restoring the fix: the file still uses dynamic_cast<…>(transport.Get()); Get() returns a reference, so we need &transport.Get().
testSuiteFlow.cpp
+1
-1
auto *zTransport = dynamic_cast<ZeroTransport *>(transport.Get());
auto *zTransport = dynamic_cast<ZeroTransport *>(&transport.Get());
if (zTransport == nullptr) {
The compiler error is from using dynamic_cast on a reference: Get() returns ITransport&, so the operand must be a pointer.
Use the address of that reference:
auto *zTransport = dynamic_cast<ZeroTransport *>(&transport.Get());
That was missing again in your tree; it’s applied now. Re-run the build.
Why: dynamic_cast<T*>(x) needs x to be a pointer (or you use dynamic_cast<T&>(ref) for references). transport.Get() is the object, not a pointer, so you need &transport.Get() to get an ITransport*.
```
