简体   繁体   中英

Call to non-constexpr function 'std::map…'

I'm attempting to create a pseudo-media center thing on an Arduino and a breadboard, not all that complicated but this is my first project with C++ that amounted to more than 'Hello world!' or a calculator.

Digressing to my point though, I started rewriting almost the entire original program, and in an effort to clean things up, started using a map to hold the keys and values (IR codes), and to further organize it, put the assignments inside of a function (IR_generateMap()), but I'm getting an error when I compile it.

C:\Users\trevo\Documents\Arduino\improvedIRRemote\improvedIRRemote.ino: In function 'void IRLoop(bool)':

improvedIRRemote:78: error: call to non-constexpr function 'std::map<Key, T, Compare, Allocator>::reference std::map<Key, T, Compare, Allocator>::operator[](const key_type&) [with Key = std::basic_string<char>; T = int; Compare = std::less<std::basic_string<char> >; Allocator = std::allocator<int>; std::map<Key, T, Compare, Allocator>::reference = int&; std::map<Key, T, Compare, Allocator>::key_type = std::basic_string<char>]'

       case IRCodes["Power Button"]:

                                  ^

improvedIRRemote:78: error: call to non-constexpr function 'std::map<Key, T, Compare, Allocator>::reference std::map<Key, T, Compare, Allocator>::operator[](const key_type&) [with Key = std::basic_string<char>; T = int; Compare = std::less<std::basic_string<char> >; Allocator = std::allocator<int>; std::map<Key, T, Compare, Allocator>::reference = int&; std::map<Key, T, Compare, Allocator>::key_type = std::basic_string<char>]'

exit status 1
call to non-constexpr function 'std::map<Key, T, Compare, Allocator>::reference std::map<Key, T, Compare, Allocator>::operator[](const key_type&) [with Key = std::basic_string<char>; T = int; Compare = std::less<std::basic_string<char> >; Allocator = std::allocator<int>; std::map<Key, T, Compare, Allocator>::reference = int&; std::map<Key, T, Compare, Allocator>::key_type = std::basic_string<char>]'

I've looked up and attempted to understand errors with non-constexpr calls, but to be perfectly honest, I don't understand how what I'm trying to do with the map relates to the problems being described in the posts that deal with said error.

#include <IRremote.h>
#include <StandardCplusplus.h>
#include <map>

//Variables responsible for recieving and decoding IR signals/codes.
IRrecv receiver(10);    //IR receiver initialization.
decode_results results; //Object that is responsible for decoding the IR signal.

//Variables responsible for tracking channel changing.
int channel = 1;                          //The active channel.
int desiredChannel = "";                  //The string that is used to concatenate the numbers pressed on the remote keypad together.
int channelEnterDelay = 4000;             //The delay between the last time a number was pressed on the remote keypad and when the desiredChannel is cleared.
unsigned long channelEnterStartTime = 0;  //The time in which that last number was pressed on the remote keypad.
String intConverter;                      //The string responsible for casting an integer to a string.

//Variables responsible for tracking volume changing.
int volume = 50;      //The current volume.
int lastVolume = 50;  //Holds the value of the volume previous to the volume being muted.
bool isMuted = false; //Whether or not the sound has been muted.

//Map responsible for the setting and getting of IR codes and their respective keys.
const std::map<std::string, int> IRCodes;

//Miscellanious Stuff - mostly waiting for depreciation.
int IRFlasherPin = 8;
int mode = 0;
int IRFlasherBlinkRate = 10;

//Debug mode shows channel switching info when entering from the remote keypad, turn it off to declutter the serial feed if it is not being used.
bool DEBUG_MODE = false;

void setup() {

  receiver.enableIRIn();          //Tells the receiver to start listening for IR communication.
  pinMode(IRFlasherPin, OUTPUT);  //Configuring the pin that flashes upon recieving the 'excess communication' IR code.
  Serial.begin(9600);             //Begins serial communication at 9600 baud.
  IR_generateMap();               //Sets all of the values for the map of IR keys and values.

  //Ready message.
  Serial.println("The Arduino is ON and ready for communication.");
  if (DEBUG_MODE) { Serial.println("Also please note that debug mode has been preemptively enabled. The serial monitor can be expected to be much more cluttered than normal. To disable this, press the 'U/SD' button on the remote."); }
  Serial.println();

}

void loop() {

  //Pre-loop checks.
  //empty

  IRLoop(true);

}

void IRLoop(bool toldToContinueLooking) {

  if (receiver.decode(&results)) {

    switch(results.value) {

      case IRCodes["Power Button"]:
        Serial.println("Power Toggle");
        break;

      default:
        if (DEBUG_MODE) {

          Serial.print("Extraneous code: ");
          Serial.print(results.value);

        }
        break;

    }

  }

  if (toldToContinueLooking) { receiver.resume(); }

}

void IR_generateMap() {

  //General Keys
  IRCodes["Power Button"] = 16753245;
  IRCodes["Mode Button"]          = 16736925;
  IRCodes["Back Button"]          = 16750695;
  IRCodes["EQ Button"]            = 16769055;
  IRCodes["USD Button"]           = 16756815;

  //Media Keys
  IRCodes["PlayPause Button"]     = 16720605;
  IRCodes["Rewind Button"]        = 16712445;
  IRCodes["Fast Forward Button"]  = 16761405;

  //Volume Keys
  IRCodes["Mute Button"]          = 16769565;
  IRCodes["Minus Button"]         = 16754775;
  IRCodes["Plus Button"]          = 16748655;

  //Numpad Keys
  IRCodes["Numpad 0"]             = 16738455;
  IRCodes["Numpad 1"]             = 16724175;
  IRCodes["Numpad 2"]             = 16718055;
  IRCodes["Numpad 3"]             = 16743045;
  IRCodes["Numpad 4"]             = 16716015;
  IRCodes["Numpad 5"]             = 16726215;
  IRCodes["Numpad 6"]             = 16734885;
  IRCodes["Numpad 7"]             = 16728765;
  IRCodes["Numpad 8"]             = 16730805;
  IRCodes["Numpad 9"]             = 16732845;

  //Non-Key Codes
  IRCodes["Excess Communication"] = 4294967295;

}

Can someone explain what I'm doing wrong to me in terms that someone of my early C++ knowledge-base would understand?

The expression in the 'case' must be compile time constant. Just use an if/else construction instead and it should work.

Thomas

I'd go in opposite way by using map to decode IR Code to handler function or by using enum . Something like this:

#include <StandardCplusplus.h>
#include <map>
#include <functional>

void power_key();
void num_key0();
void num_key1();
void num_key2();
void num_key3();
void num_key4();
void num_key5();
void num_key6();
void num_key7();
void num_key8();
void num_key9();
void num_key(int8_t);

typedef void(*handler_t)();

std::map<uint32_t, handler_t> keys;


void setup() {
  keys[16753245UL] = power_key;
  keys[16738455UL] = num_key0;
  keys[16724175UL] = num_key1;
  keys[16718055UL] = num_key2;
  keys[16743045UL] = num_key3;
  keys[16716015UL] = num_key4;
  keys[16726215UL] = num_key5;
  keys[16734885UL] = num_key6;
  keys[16728765UL] = num_key7;
  keys[16730805UL] = num_key8;
  keys[16732845UL] = num_key9;


  Serial.begin(57600);
}

void loop() {

  uint32_t recvd_code = 16753245UL; // literal value, for testing purpose without IR receiver and remote

  auto iter = keys.find(recvd_code); // find received code and execute it
  if (iter != keys.end()) {
    iter->second();
  } else {
    Serial.print(F("IR Code "));
    Serial.print(recvd_code);
    Serial.println(F("not found"));
  }

  delay(1000);
}

void power_key() {
    Serial.println(F("Power key pressed"));  
}

void num_key0() { num_key(0); }
void num_key1() { num_key(1); }
void num_key2() { num_key(2); }
void num_key3() { num_key(3); }
void num_key4() { num_key(4); }
void num_key5() { num_key(5); }
void num_key6() { num_key(6); }
void num_key7() { num_key(7); }
void num_key8() { num_key(8); }
void num_key9() { num_key(9); }

void num_key(int8_t num) {
   Serial.print(F("Numeric key pressed: "));
   Serial.println(num);
}

Initializer list somehow didin't work, so initialization must be done in setup and map can't be const .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM