Possible to use C++17

See updated issue. When using the right branch it goes through and C++17 std::optional features are usuable. I copied the example from the cppreference page and it produces the expected output.

Full platformio.ini:

[esp32]
; upgrade XTensa32 GCC/G++ compiler to 8.2.0
; use bleeding edge arduino-esp32
platform_packages =
    toolchain-xtensa32 @ 2.80200.200226
    framework-arduinoespressif32 @ https://github.com/espressif/arduino-esp32.git#idf-release/v4.0

[common]
build_flags =
; do not redefine arduino
;    -DARDUINO=10800 
    -DESP32=1
    -DARDUINO_ARCH_ESP32=1
    -DBOARD_HAS_PSRAM
    -std=c++17
; only use C++17 now not GNU++17. This is an either-or relation.
;    -std=gnu++17
build_unflags =
    -std=gnu++11

[env:planter]
board = esp32doit-devkit-v1
framework = arduino
platform = espressif32
platform_packages =
    ${esp32.platform_packages}
; not given in examples
;lib_deps =
;    ${common.lib_deps}
build_flags =
    ${common.build_flags}
build_unflags =
	${common.build_unflags}

main.cpp

#include <Arduino.h>
#include <string>
#include <functional>
#include <iostream>
#include <optional>


// optional can be used as the return type of a factory that may fail
std::optional<std::string> create(bool b) {
    if (b)
        return "Godzilla";
    return {};
}

// std::nullopt can be used to create any (empty) std::optional
auto create2(bool b) {
    return b ? std::optional<std::string>{"Godzilla"} : std::nullopt;
}

// std::reference_wrapper may be used to return a reference
auto create_ref(bool b) {
    static std::string value = "Godzilla";
    return b ? std::optional<std::reference_wrapper<std::string>>{value}
             : std::nullopt;
}

int main2()
{
    std::cout << "create(false) returned "
              << create(false).value_or("empty") << '\n';

    // optional-returning factory functions are usable as conditions of while and if
    if (auto str = create2(true)) {
        std::cout << "create2(true) returned " << *str << '\n';
    }

    if (auto str = create_ref(true)) {
        // using get() to access the reference_wrapper's value
        std::cout << "create_ref(true) returned " << str->get() << '\n';
        str->get() = "Mothra";
        std::cout << "modifying it changed it to " << str->get() << '\n';
    }
    return 0;
}

void setup() {
	Serial.begin(115200);
	main2();
}

void loop() {
}

Produces

rst:0x10 (RTCWDT_RTC_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)
configsip: 0, SPIWP:0xee
clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
mode:DIO, clock div:2
load:0x3fff0018,len:4
load:0x3fff001c,len:1364
load:0x40078000,len:12656
load:0x40080400,len:3512
entry 0x40080624
create(false) returned empty
create2(true) returned Godzilla
create_ref(true) returned Godzilla
modifying it changed it to Mothra

So it should be all fine now. Since this uses bleeding-edge version of the Arduino-ESP32’s idf-release/v4.0 branch I can’t say much about the stability of this branch, but I’m sure some time later a stable version will be released as an update…

3 Likes