2

I seem to have the following problem. I have a class BSK (Binary Knapsack) which contains a struct Item in which an identifier can be std::string or int. Then I have a vector<Items> itemlist_ and I need to insert a new Item in the beginning. I am trying to do something like this and it works for int but does not work for string. Thank you!

template <class T>
class BKS final
{
public:
    struct Item
    {
        T identifier;
        int weight;
        int benefit;
    };
     // some methods ...
}

I am trying to do something like this and it works for int but does not work for string. Thank you!

if(std::is_same<T, int>::value){
    Item toInsert = {0,0,0};
    itemlist_.insert(itemlist_.begin(), toInsert);
else{
    Item toInsert = {"aa", 0, 0};
    itemlist_.insert(itemlist_.begin(), toInsert);
}
Nikola
  • 133
  • 9

2 Answers2

3

The problem is that both the if part and else part have to be well-formed at compile-time. The statement Item toInsert = {"aa", 0, 0}; is ill-formed when T is int.

You can use constexpr if (since C++17).

If the value is true, then statement-false is discarded (if present), otherwise, statement-true is discarded.

if constexpr (std::is_same<T, int>::value) {
    Item toInsert = {0,0,0};
    itemlist_.insert(itemlist_.begin(), toInsert);
} else {
    Item toInsert = {"aa", 0, 0};
    itemlist_.insert(itemlist_.begin(), toInsert);
}
songyuanyao
  • 169,198
  • 16
  • 310
  • 405
1

You need to instantiate the correct (only one of) part of if at compile time. Normal if statement can not do that. Read more:

Difference between "if constexpr()" Vs "if()"

You need if-constexpr.

Suggestion: In addition, you do not need extra toInsert, pass the temporary, to the itemlist_.

if constexpr (std::is_same<T, int>::value)
{
    itemlist_.insert(itemlist_.begin(), {0,0,0});
} 
else if constexpr(std::is_same<T, std::string>::value)
{
    itemlist_.insert(itemlist_.begin(), {"aa", 0, 0});
}
UserUsing
  • 678
  • 1
  • 5
  • 16