_dynamic_ array initialization
This is a bit weird, but here goes.
I have many hardcoded "tables" that I'm defining as arrays of std::strings
or const char *
.
So for example:
const char* resp_desc[] = {
"00=Approved",
"开发者_如何学C01=Declined",
"03=Incorrect User name",
// more values
NULL
};
In some functions these are passed as the table to lookup the description:
const char* lookup(const char* code, const char** table, const char*default="") {
// lookup code is here..
}
my question is, is it possible to call the lookup function without creating the resp_desc array?
The below code was my first attempt, but I get syntax errors around the {}
when trying to use it:
const char* desc = lookup("00", {"00=Approved", "01-Invalid Record", NULL})
It doesn't work with the current C++03, but C++0x will allow to initialize i.e. std::vector with
std::vector<std::string>{"00=Approved", "01-Invalid Record"}
Edit: This works with g++ --std=c++0x (gcc --version is 4.4.3)
#include <iostream>
#include <vector>
#include <string>
#include <algorithm>
using namespace std;
bool contains(string item, vector<string> const& table) {
return find(table.begin(), table.end(), item) != table.end();
}
int main() {
cout << (contains("foo", vector<string>{"foo", "bar"}) ? "found" : "not found") << "\n";
return 0;
}
If you are willing to change your look-up function, you could alternatively use utilities like Boost.Assign:
// alternative lookup function:
std::string lookup(const std::string& code,
const std::vector<std::string>& table,
const std::string& default="");
// example:
const std::string desc = lookup("00", boost::assign::list_of
("00=Approved")("01-Invalid Record"));
or maybe simply something like this:
typedef std::map<std::string,std::string> Table;
std::string lookup(const std::string& code,
const Table& table,
const std::string& default="")
{
Table::iterator it = table.find(code);
return (it != table.end()) ? it->second : default;
}
const std::string desc = lookup("00", boost::assign::map_list_of
("00","Approved")("01","Invalid Record"));
In short, no. C++ doesn't provide array or structure literals, only array or structure initializers. That is, the { yadda, yadda, yadda }
syntax only means what you want when it occurs on the right side of sometype name[] =
.
The answer is no.
In C++ (and also C), array types in function parameters are automatically converted to pointer types, as your signature for lookup shows:
const char* lookup(const char* code, const char** table, const char *default);
table
is a const char **
and so needs a pointer value. To have a pointer, you need an object in memory to point at.
If you had a simple function such as:
void myfunc(int foo);
you can call myfunc(1)
and that's fine. The constant expression 1
is a temporary value which doesn't have a location in memory, and myfunc
receives the value directly.
If however you call your lookup function:
const char* desc = lookup("00", /* array constant */);
we can ask: what could /* array constant */
possibly be? lookup
needs a pointer to an array object which exists somewhere in memory; but a constant expression doesn't have a location in memory (it is not an lvalue or object) and so there can be no pointer which refers to the constant array expression. As a result, such constant expressions do not exist.
(The one exception to this rule of "no constants which decay to pointers" is the string literal: "Hello World"
. A string literal creates an array in memory with static duration which exists for the lifetime of the program, and its value returned is a const char *
pointing to that array. Sadly, the equivalent for array literals does not exist.)
No sir! The curly bracket syntax is for array initialization only. It does not represent a literal array.
精彩评论