Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 6144761
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: May 23, 20262026-05-23T18:41:55+00:00 2026-05-23T18:41:55+00:00

In joint with this question . I am having trouble coming up with a

  • 0

In joint with this question. I am having trouble coming up with a good type safe solution to the following seemingly basic problem. I have a class music_playlist that has a list of the songs it should play. Seems pretty simple right, just make an std::list of all the songs in queue, and make it available to the user. However, out of necessity the audio decoding, and the audio rendering happens on separate threads. So the list needs to be mutex protected. Often times the mutex was forgotten by other programmers using my library. Which obviously led to "strange" problems.

So at first I just wrote setters for the class.

struct music{};
class music_playlist{
private:
     std::list<music> playlist;
public:
     void add_song(music &song){playlist.push_back(song);}
     void clear(){playlist.clear();}
     void set_list(std::list<music> &songs){playlist.assign(songs.begin(),songs.end());}
//etc
};

This led to user code like below…

music song1;
music song2;
music song3;
music song4;
music song5;
music song6;
music_playlist playlist1;
playlist1.add_song(song1);
playlist1.add_song(song2);
playlist1.add_song(song3);
playlist1.add_song(song4);
playlist1.add_song(song5);
playlist1.add_song(song6);

//or
music_playlist playlist2;
std::list<music> songs;
songs.push_back(song1);
songs.push_back(song2);
songs.push_back(song3);
songs.push_back(song3);
songs.push_back(song5);
songs.push_back(song6);
playlist2.set_list(songs);

While this works and is very explicit. It is very tedious to type out and it is bug prone due to all the cruft around the actual work. To demonstrate this, I actually intentionally put a bug into the above code, something like this would be easy to make and would probably go through code reviews untouched, while song4 never plays in playlist 2.

From there I went to look into variadic functions.

struct music{};
class music_playlist{
private:
     std::list<music> playlist;
public:
     void set_listA(music *first,...){
     //Not guaranteed to work, but usually does... bleh
         va_list Arguments;
    va_start(Arguments, first);
    if (first) {
        playlist.push_back(first);
    }
    while (first) {
        music * a = va_arg(Arguments, music*);
        if (a) {
            playlist.push_back(a);
        }else {
            break;
        }
    }
    }
    void set_listB(int count,music first,...){
         va_list Arguments;
     va_start(Arguments, first);
     playlist.push_back(first);

    while (--count) {
        music a = va_arg(Arguments, music);
            playlist.push_back(a);
    }
    }
//etc
}; 

Which would lead to a users code like below…

playlist1.set_listA(&song1,&song2,&song3,&song4,&song5,&song6,NULL);
//playlist1.set_listA(&song1,&song2,&song3,&song4,&song5,&song6); runtime error!!
//or
playlist2.set_listB(6,song1,song2,song3,song4,song5,song6);

Now its much easier to see if a song was added twice or not included. However in solution A it will crash if NULL is not at the end of the list, and is not cross platform. In solutionB you have to count the amount of arguments which can lead to several bugs. Also, none of the solutions are type safe, and the user could pass in an unrelated type and wait for the crash at runtime. This didn’t seem to be a sustainable solution. So then I came across std::initializer_list. Can’t use it several of the compilers I develop for don’t have support for it yet. So I tried to emulate it. I ended up with this solution below.

Is this use of the "," operator considered bad form?

Which would lead to a users code looking like this…

struct music_playlist{
    list<music> queue;
//...
};
int main (int argc, const char * argv[])
{
    music_playlist playlist;
    music song1;
    music song2;
    music song3;
    music song4;
    playlist.queue = song1,song2; // The queue now contains song1 and song2
    playlist.queue+= song1,song3,song4; //The queue now contains two song1s and song2-4
    playlist.queue = song2; //the queue now only contains song2
    return 0;
}

This syntax was not confusing to our small testgroup. However, I had serious concerns with abusing operator overloading so severely. So I posted the question above. I wanted to see what programmers that were comparatively experts to our test group thought. Quite alot of programmers did not like it however it seemed better than the above solutions because it would catch most bugs at compile time instead of just at run time. However Tom posted an interesting counter example, that would cause unexpected behavior.

//lets combine differnt playlists
new_playlist.queue =    song1        //the first playlist
                      ,(song3,song4) //the second playlist //opps, I didn't add song 3!
                      , song5;

This sours me to that solution. So do you have any ideas about a better solution?

P.S. None of the above code was compiled, they are just there for example purposes.

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-05-23T18:41:55+00:00Added an answer on May 23, 2026 at 6:41 pm

    The first question that comes to mind is whether this is a problem, and whether this is a problem worth the solution. Since you are creating an interface, your client will be user code (not people, code). How many times will your clients hardcode playlists in the code versus say, store load them from a file or construct them from their user selections?

    Think on the actual value of the feature and compare that with the impact that it will have in how they use your library, and think on how many problems your users might have with the changed interface.

    The simplest solution is accepting iterators to construct/reset your list, and then let the users deal with the problem. Of course they can build their own container in the way that you have shown, but they can also use Boost.Assignment to take care of the boiler plate, so their user code will look like:

    std::vector<music> songs = boost::assign::list_of()( song1 )( song2 );
    play_list.set( songs.begin(), songs.end() );
    

    Or if they are not comfortable with that library the can use a plain old array:

    music songs[2] = { song1, song2 };
    play_list:set( songs, songs + 2 ); // add your preferred magic to calculate the size
    
    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

Ok so this is probably a trivial question but I'm having trouble visualizing and
I know this question has been asked many times, but I am having trouble
This is a theoretical question. I'm having trouble defining the question so please bear
I am having trouble with a SQL join question. I have a table EMPLOYEE
I'm having trouble figuring out the solution to this SQL query. Schema Edit :
There is probably an obvious answer to this question, but I am having one
I'm having trouble getting the Jquery Validation to work with the following rules. I
I've seen a few different versions of this question but having difficulty applying it
Now I have seen this question in another forum but it didn't had an
This is probably really easy, but I am having trouble with it. I asked

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.