Can I put this in a .h file?

J

jessica_boxer

I want a standard list of strings, which I want to implement in a
header as:

// Approach 1 in .h
namespace StdNames
{
const char* name1 = "Name1";
const char* name2 = "Name2";
// etc
}

If I put this in the header will it allocate space for name1 and name2
everywhere I include the header (meaning I should have a corresponding
cpp file that actually does the assignments, and declars the above as
extern) or does it treat these as logical constants? Is Approach 1
above, or apporach 2 more appropriate?


// Approach 2 in .h
namespace StdNames
{
extern const char* name1;
extern const char* name2;
// etc
}

// And in the .cpp file
#include "StdNames.h"

namespace StdNames
{
const char* name1 = "Name1";
const char* name2 = "Name2";
// etc
}
 
A

Alf P. Steinbach

* (e-mail address removed):
I want a standard list of strings, which I want to implement in a
header as:

// Approach 1 in .h
namespace StdNames
{
const char* name1 = "Name1";
const char* name2 = "Name2";
// etc
}

If I put this in the header will it allocate space for name1 and name2
everywhere I include the header

That's a quality of implementation issue.

There are workarounds where you want a guarantee, e.g., using
non-template code only,

namespace StdNames
{
inline std::vector<char const*> names()
{
static char const* values[] =
{
"Name1",
"Name2",
};
return std::vector<char const*>( values, values+2 )
}
}

where the literal constant 2 should of course be replaced by some
function or macro.

(meaning I should have a corresponding
cpp file that actually does the assignments, and declars the above as
extern) or does it treat these as logical constants? Is Approach 1
above, or apporach 2 more appropriate?


// Approach 2 in .h
namespace StdNames
{
extern const char* name1;
extern const char* name2;
// etc
}

// And in the .cpp file
#include "StdNames.h"

namespace StdNames
{
const char* name1 = "Name1";
const char* name2 = "Name2";
// etc
}

If you're happy to have a .cpp file then this is also perfectly OK.

One limitation is that you cannot then use such constants in compile
time expressions such as, for pointers, template instantiations.

However, the technique I sketched above does not solve that either, and
although a "simple" template solution exists the problem it solves seems
to not occur in practice... ;-)
 
A

Alf P. Steinbach

* Alf P. Steinbach:
* (e-mail address removed):

That's a quality of implementation issue.

Sorry, forgot: IF (and I mean IF) what you meant was to have constants,
not variables, i.e.

char const *const name1 = "Name1";

which you can alternatively and better (preserving length information)
express as

char const name1[] = "Name1";

THEN it's a quality of implementation issue.

If, on the other hand, you really mean variables, then the answer is
that you're in violation of the "one definition rule" (ODR). That's
because while namespace scope constants have internal linkage as
default, namespace scope variables have external linkage as default.

In the rest of my posting, insert extra 'const''s as appropriate... ;-)
 
G

Gernot Frisch

namespace StdNames
{
inline std::vector<char const*> names()
{
static char const* values[] =
{
"Name1",
"Name2",
};
return std::vector<char const*>( values, values+2 )
}
}

where the literal constant 2 should of course be replaced by some
function or macro.

return std::vector<char const*>(values, sizeof(values)/sizeof(char
const*) );

e.g.
 
R

red floyd

Gernot said:
namespace StdNames
{
inline std::vector<char const*> names()
{
static char const* values[] =
{
"Name1",
"Name2",
};
return std::vector<char const*>( values, values+2 )
}
}

where the literal constant 2 should of course be replaced by some
function or macro.

return std::vector<char const*>(values, sizeof(values)/sizeof(char
const*) );

I'd write the whole thing as follows:

namespace StdNames
{
inline const std::vector<char const *>& names()
{
static char const* const values[] =
{
"Name1",
"Name2",
// ...
};
static const std::vector<char const*>
theVector(values, values+sizeof(values)/sizeof(values[0]));
return theVector;
}
}

You don't make multiple copies of the vector, you can't add values to
your standard names, and you can't change your names.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,770
Messages
2,569,583
Members
45,075
Latest member
MakersCBDBloodSupport

Latest Threads

Top