0

Is it possible to call a function within a namespace? I need to do this because the function assigns meaningful values to the variables. If not, is there a workaround? An idea of what I want is below, with foo the function within which the variables are assigned values, and bar1, bar2 the two variables to be given values.

namespace space{
    bar *bar1;
    bar *bar2;

    void foo(bar *b1, bar *b2) {/*b1 and b2 and given values*/}
    foo(bar1, bar2); // this foo is a function call.
}

To clarify, bar1 and bar2 should be defined only the first time they are called and no other time.

12
  • 3
    I'm not sure what you mean by "call a function within a namespace"... perhaps this is a rephrasing of the question you asked 2 hours ago? Commented Jul 18, 2015 at 3:05
  • @DrewDormann close but not exactly. The other one requires singleton pattern. My actual code (not shown) has accomplished this inside a class. Now I want to set a namespace variable to the singleton value (two variable, singleton pairs actually) so that whenever a user wishes to access the variable he or she can do so via the namespace and not via the class. I was hoping the example would clarify. Is there a way to define the values of namespace variables by means of a function. Commented Jul 18, 2015 at 3:22
  • When, during your program's execution, would you need this function to be run? Commented Jul 18, 2015 at 3:25
  • 1
    C++ does not directly support that. The closest you may get is executing functions whenever someone accesses the object via a "smart container" class that overrides operator->. I'd give you a full answer but I'm about to chow on some awesome bacon wrapped dogs on a whole wheat bun. Commented Jul 18, 2015 at 3:54
  • 1
    I think your assessment of how helpful SO has been is off base. Drew took the time to get clarification of your post, someone provided an answer, and I made a high level suggestion while those juicy succulent hotdogs were calling out my name like a horny prom date. Your post is unclear and while salvageable the lack of clarity has limited the response. Although you provided some clarification in comments those comments should be moved into your post. That wold certainly make me more inclined to put time into providing a potentially acceptable solution based on my earlier comment. 600 chars!! Commented Jul 18, 2015 at 14:00

1 Answer 1

1

This does, I believe, exactly what the OP wants, but it's horrible. Every CPP file that includes space.h is going to instantiate bar's 1 and 2 and init. Naming collision hell when the linker tries to sort it all out.

#ifndef SPACE_H
#define SPACE_H
#include <iostream>
namespace space
{
    class bar
    {
    public:
        // use your own stuff here. This is for sample use only.
        bar(const std::string & str):mStr(str)
        {

        }
        friend std::ostream &operator<<(std::ostream & out, const bar &bq)
        {
            out << bq.mStr;
            return out;
        }
    private:
        std::string mStr;
    };
    bar *bar1; // consider using std::unique_ptr in place of the raw pointer
    bar *bar2;

    class Init
    {
    public:
        Init()
        {
            bar1 = new bar("bar, bar, bar");
            bar2 = new bar("barbara anne");
        }
        virtual ~Init() // std::unique_ptr makes this destructor unnecessary
        {
             delete bar1;
             delete bar2;
        }
    }
    Init init; // init will construct and assign the bars before main 
               // and destruct and delete the bars when the program exits
}
#endif

static makes it marginally better static restricts each bar and init to each including CPP file, but now you have the variables duplicated in each including CPP file, more RAM use and changing one does not change the others.

    static bar *bar1;
    static bar *bar2;

    class Init
    {
    public:
        Init()
        {
            bar1 = new bar("bar, bar, bar");
            bar2 = new bar("barbara anne");
        }
        virtual ~Init()
        {
             delete bar1;
             delete bar2;
        }
    };
    static Init init;

Another tweak doesn't do exactly what OP wants, but it's close, a lot safer that take 1, and unified across compilation units unlike take 2. extern instructs the compiler to allow use of bars 1 and 2 without instantiating them, but that means someone has to actually allocate space for them.

    extern bar *bar1;
    extern bar *bar2;

    class Init
    {
    public:
        Init()
        {
            bar1 = new bar("bar, bar, bar");
            bar2 = new bar("barbara anne");
        }
        virtual ~Init()
        {
             delete bar1;
             delete bar2;
        }
    };

And a main CPP to demonstrate use

#include <iostream>
#include "space.h"

// allocate the bars and the Init object
space::bar *space::bar1; 
space::bar *space::bar2;

space::Init init;

int main()
{
    std::cout << *space::bar1 << std::endl;
    std::cout << *space::bar2 << std::endl;
    return 0;
}
Sign up to request clarification or add additional context in comments.

1 Comment

I ended up discovering the extern take last night. But the other two takes are fascinating. Answer goes to you because of completeness and clarity.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.