Is there a way to specify an enum-class value without having to type out its scope every time?
I have some functions that can return either success or one of a fixed set of error codes. To identify the error codes, I had (something like) this old-school C-style enum declared:
enum {
RESULT_ERROR_BAD_PARAMETER = -3,
RESULT_ERROR_FILE_NOT_FOUND = -2,
RESULT_ERROR_GENERAL = -1,
RESULT_SUCCESS = 0
};
typedef int my_status_t;
my_status_t MyFunc(); // returns a RESULT_* value
This worked pretty well; the calling pattern would be something like:
if (MyFunc() != RESULT_SUCCESS) printf("Error!n");
... however it was uncomfortably permissive about allowing implicit conversions of my_status_t
values to int/bool/etc, allowing careless mistakes like this:
// Compiles but does the wrong thing at run-time -- bad!
if (MyFunc() == false) printf("Error!n");
... so in my new code revision, I converted it to be an enum class
instead:
enum class my_status_t {
RESULT_ERROR_BAD_PARAMETER = -3,
RESULT_ERROR_FILE_NOT_FOUND = -2,
RESULT_ERROR_GENERAL = -1,
RESULT_SUCCESS = 0
};
... this works great from a compile-time checking perspective; now most unintentional type-promotions are caught by the compiler, forcing the programmer to go back and do it the right way.
The only thing that bothers me is that the new syntax is tedious: now I have to write something like:
if (MyFunc() != my_status_t::RESULT_SUCCESS) printf("Error!n");
... at every call site -- having to type out my_status_t::
each time is tedious and makes the code harder to read, without really adding much value (since RESULT_SUCCESS
is sufficiently unique for my purposes on its own, anyway)
My question is, is there some kind of using namespace my_status_t;
style directive I could use to tell the compiler to export the enum-values out of their my_status_t
namespace, so that I could reference them without having to type the my_status_t::
prefix all the time?
c++ c++11 enums namespaces
add a comment |
I have some functions that can return either success or one of a fixed set of error codes. To identify the error codes, I had (something like) this old-school C-style enum declared:
enum {
RESULT_ERROR_BAD_PARAMETER = -3,
RESULT_ERROR_FILE_NOT_FOUND = -2,
RESULT_ERROR_GENERAL = -1,
RESULT_SUCCESS = 0
};
typedef int my_status_t;
my_status_t MyFunc(); // returns a RESULT_* value
This worked pretty well; the calling pattern would be something like:
if (MyFunc() != RESULT_SUCCESS) printf("Error!n");
... however it was uncomfortably permissive about allowing implicit conversions of my_status_t
values to int/bool/etc, allowing careless mistakes like this:
// Compiles but does the wrong thing at run-time -- bad!
if (MyFunc() == false) printf("Error!n");
... so in my new code revision, I converted it to be an enum class
instead:
enum class my_status_t {
RESULT_ERROR_BAD_PARAMETER = -3,
RESULT_ERROR_FILE_NOT_FOUND = -2,
RESULT_ERROR_GENERAL = -1,
RESULT_SUCCESS = 0
};
... this works great from a compile-time checking perspective; now most unintentional type-promotions are caught by the compiler, forcing the programmer to go back and do it the right way.
The only thing that bothers me is that the new syntax is tedious: now I have to write something like:
if (MyFunc() != my_status_t::RESULT_SUCCESS) printf("Error!n");
... at every call site -- having to type out my_status_t::
each time is tedious and makes the code harder to read, without really adding much value (since RESULT_SUCCESS
is sufficiently unique for my purposes on its own, anyway)
My question is, is there some kind of using namespace my_status_t;
style directive I could use to tell the compiler to export the enum-values out of their my_status_t
namespace, so that I could reference them without having to type the my_status_t::
prefix all the time?
c++ c++11 enums namespaces
add a comment |
I have some functions that can return either success or one of a fixed set of error codes. To identify the error codes, I had (something like) this old-school C-style enum declared:
enum {
RESULT_ERROR_BAD_PARAMETER = -3,
RESULT_ERROR_FILE_NOT_FOUND = -2,
RESULT_ERROR_GENERAL = -1,
RESULT_SUCCESS = 0
};
typedef int my_status_t;
my_status_t MyFunc(); // returns a RESULT_* value
This worked pretty well; the calling pattern would be something like:
if (MyFunc() != RESULT_SUCCESS) printf("Error!n");
... however it was uncomfortably permissive about allowing implicit conversions of my_status_t
values to int/bool/etc, allowing careless mistakes like this:
// Compiles but does the wrong thing at run-time -- bad!
if (MyFunc() == false) printf("Error!n");
... so in my new code revision, I converted it to be an enum class
instead:
enum class my_status_t {
RESULT_ERROR_BAD_PARAMETER = -3,
RESULT_ERROR_FILE_NOT_FOUND = -2,
RESULT_ERROR_GENERAL = -1,
RESULT_SUCCESS = 0
};
... this works great from a compile-time checking perspective; now most unintentional type-promotions are caught by the compiler, forcing the programmer to go back and do it the right way.
The only thing that bothers me is that the new syntax is tedious: now I have to write something like:
if (MyFunc() != my_status_t::RESULT_SUCCESS) printf("Error!n");
... at every call site -- having to type out my_status_t::
each time is tedious and makes the code harder to read, without really adding much value (since RESULT_SUCCESS
is sufficiently unique for my purposes on its own, anyway)
My question is, is there some kind of using namespace my_status_t;
style directive I could use to tell the compiler to export the enum-values out of their my_status_t
namespace, so that I could reference them without having to type the my_status_t::
prefix all the time?
c++ c++11 enums namespaces
I have some functions that can return either success or one of a fixed set of error codes. To identify the error codes, I had (something like) this old-school C-style enum declared:
enum {
RESULT_ERROR_BAD_PARAMETER = -3,
RESULT_ERROR_FILE_NOT_FOUND = -2,
RESULT_ERROR_GENERAL = -1,
RESULT_SUCCESS = 0
};
typedef int my_status_t;
my_status_t MyFunc(); // returns a RESULT_* value
This worked pretty well; the calling pattern would be something like:
if (MyFunc() != RESULT_SUCCESS) printf("Error!n");
... however it was uncomfortably permissive about allowing implicit conversions of my_status_t
values to int/bool/etc, allowing careless mistakes like this:
// Compiles but does the wrong thing at run-time -- bad!
if (MyFunc() == false) printf("Error!n");
... so in my new code revision, I converted it to be an enum class
instead:
enum class my_status_t {
RESULT_ERROR_BAD_PARAMETER = -3,
RESULT_ERROR_FILE_NOT_FOUND = -2,
RESULT_ERROR_GENERAL = -1,
RESULT_SUCCESS = 0
};
... this works great from a compile-time checking perspective; now most unintentional type-promotions are caught by the compiler, forcing the programmer to go back and do it the right way.
The only thing that bothers me is that the new syntax is tedious: now I have to write something like:
if (MyFunc() != my_status_t::RESULT_SUCCESS) printf("Error!n");
... at every call site -- having to type out my_status_t::
each time is tedious and makes the code harder to read, without really adding much value (since RESULT_SUCCESS
is sufficiently unique for my purposes on its own, anyway)
My question is, is there some kind of using namespace my_status_t;
style directive I could use to tell the compiler to export the enum-values out of their my_status_t
namespace, so that I could reference them without having to type the my_status_t::
prefix all the time?
c++ c++11 enums namespaces
c++ c++11 enums namespaces
edited Nov 21 '18 at 18:53
Yakk - Adam Nevraumont
187k20199383
187k20199383
asked Nov 21 '18 at 15:18
Jeremy FriesnerJeremy Friesner
39.8k1080164
39.8k1080164
add a comment |
add a comment |
3 Answers
3
active
oldest
votes
If you going to be typing a lot more of the nuisance scope-prefixes than there
are constants in the enum class
, then it may be worth your while to go with this
way:
enum class result {
ERROR_BAD_PARAMETER = -3,
ERROR_FILE_NOT_FOUND = -2,
ERROR_GENERAL = -1,
SUCCESS = 0
};
constexpr result RESULT_ERROR_BAD_PARAMETER = result::ERROR_BAD_PARAMETER;
constexpr result RESULT_FILE_NOT_FOUND = result::ERROR_FILE_NOT_FOUND;
constexpr result RESULT_ERROR_GENERAL = result::ERROR_GENERAL;
constexpr result RESULT_SUCCESS = result::SUCCESS;
result foo() {
return RESULT_SUCCESS;
}
int main()
{
switch (foo())
{
case RESULT_SUCCESS:
;
}
// ^ warning: enumeration value ‘...’ not handled in ...
if (foo() == RESULT_SUCCESS) {
return 0;
}
/* error: no match for ‘operator==’
if (foo() == false) {
return -1;
}
*/
}
(g++ -Wall -Wextra -pedantic -std=c++11)
add a comment |
Do this change:
enum class result {
ERROR_BAD_PARAMETER = -3,
ERROR_FILE_NOT_FOUND = -2,
ERROR_GENERAL = -1,
SUCCESS = 0
};
because your enumerated values are in a scope, you no longer have to give them as long a name.
Now your code becomes:
if (MyFunc() != result::SUCCESS) printf("Error!n");
which is a whole 1 character longer than before.
You could also
using my_status_t = result;
if you are tied to my_status_t
as a type name.
As of C++17 there is no way to cleanly avoid the result::
prefix. There is talk about using ERROR_BAD_PARAMETER = result::ERROR_BAD_PARAMETER;
or the like in later versions of C++, but I'm unaware if they are going to get into c++20.
What I'm looking for is the ability to avoid thesomething::
prefix.
– Jeremy Friesner
Nov 21 '18 at 19:21
add a comment |
Here's a way:
enum class my_status_t { };
inline constexpr my_status_t RESULT_ERROR_BAD_PARAMETER = my_status_t(-3);
// add other enum values here
Unfortunately, this way you lose some good properties of enum
. Like compiler can warn you if you don't handle a value in a switch (and don't forget to set the underlying type of enum class
, if you have big values).
So I actually don't recommend this way (I better like Yakk's solution), but maybe this answer can help you anyway...
add a comment |
Your Answer
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53415177%2fis-there-a-way-to-specify-an-enum-class-value-without-having-to-type-out-its-sco%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
3 Answers
3
active
oldest
votes
3 Answers
3
active
oldest
votes
active
oldest
votes
active
oldest
votes
If you going to be typing a lot more of the nuisance scope-prefixes than there
are constants in the enum class
, then it may be worth your while to go with this
way:
enum class result {
ERROR_BAD_PARAMETER = -3,
ERROR_FILE_NOT_FOUND = -2,
ERROR_GENERAL = -1,
SUCCESS = 0
};
constexpr result RESULT_ERROR_BAD_PARAMETER = result::ERROR_BAD_PARAMETER;
constexpr result RESULT_FILE_NOT_FOUND = result::ERROR_FILE_NOT_FOUND;
constexpr result RESULT_ERROR_GENERAL = result::ERROR_GENERAL;
constexpr result RESULT_SUCCESS = result::SUCCESS;
result foo() {
return RESULT_SUCCESS;
}
int main()
{
switch (foo())
{
case RESULT_SUCCESS:
;
}
// ^ warning: enumeration value ‘...’ not handled in ...
if (foo() == RESULT_SUCCESS) {
return 0;
}
/* error: no match for ‘operator==’
if (foo() == false) {
return -1;
}
*/
}
(g++ -Wall -Wextra -pedantic -std=c++11)
add a comment |
If you going to be typing a lot more of the nuisance scope-prefixes than there
are constants in the enum class
, then it may be worth your while to go with this
way:
enum class result {
ERROR_BAD_PARAMETER = -3,
ERROR_FILE_NOT_FOUND = -2,
ERROR_GENERAL = -1,
SUCCESS = 0
};
constexpr result RESULT_ERROR_BAD_PARAMETER = result::ERROR_BAD_PARAMETER;
constexpr result RESULT_FILE_NOT_FOUND = result::ERROR_FILE_NOT_FOUND;
constexpr result RESULT_ERROR_GENERAL = result::ERROR_GENERAL;
constexpr result RESULT_SUCCESS = result::SUCCESS;
result foo() {
return RESULT_SUCCESS;
}
int main()
{
switch (foo())
{
case RESULT_SUCCESS:
;
}
// ^ warning: enumeration value ‘...’ not handled in ...
if (foo() == RESULT_SUCCESS) {
return 0;
}
/* error: no match for ‘operator==’
if (foo() == false) {
return -1;
}
*/
}
(g++ -Wall -Wextra -pedantic -std=c++11)
add a comment |
If you going to be typing a lot more of the nuisance scope-prefixes than there
are constants in the enum class
, then it may be worth your while to go with this
way:
enum class result {
ERROR_BAD_PARAMETER = -3,
ERROR_FILE_NOT_FOUND = -2,
ERROR_GENERAL = -1,
SUCCESS = 0
};
constexpr result RESULT_ERROR_BAD_PARAMETER = result::ERROR_BAD_PARAMETER;
constexpr result RESULT_FILE_NOT_FOUND = result::ERROR_FILE_NOT_FOUND;
constexpr result RESULT_ERROR_GENERAL = result::ERROR_GENERAL;
constexpr result RESULT_SUCCESS = result::SUCCESS;
result foo() {
return RESULT_SUCCESS;
}
int main()
{
switch (foo())
{
case RESULT_SUCCESS:
;
}
// ^ warning: enumeration value ‘...’ not handled in ...
if (foo() == RESULT_SUCCESS) {
return 0;
}
/* error: no match for ‘operator==’
if (foo() == false) {
return -1;
}
*/
}
(g++ -Wall -Wextra -pedantic -std=c++11)
If you going to be typing a lot more of the nuisance scope-prefixes than there
are constants in the enum class
, then it may be worth your while to go with this
way:
enum class result {
ERROR_BAD_PARAMETER = -3,
ERROR_FILE_NOT_FOUND = -2,
ERROR_GENERAL = -1,
SUCCESS = 0
};
constexpr result RESULT_ERROR_BAD_PARAMETER = result::ERROR_BAD_PARAMETER;
constexpr result RESULT_FILE_NOT_FOUND = result::ERROR_FILE_NOT_FOUND;
constexpr result RESULT_ERROR_GENERAL = result::ERROR_GENERAL;
constexpr result RESULT_SUCCESS = result::SUCCESS;
result foo() {
return RESULT_SUCCESS;
}
int main()
{
switch (foo())
{
case RESULT_SUCCESS:
;
}
// ^ warning: enumeration value ‘...’ not handled in ...
if (foo() == RESULT_SUCCESS) {
return 0;
}
/* error: no match for ‘operator==’
if (foo() == false) {
return -1;
}
*/
}
(g++ -Wall -Wextra -pedantic -std=c++11)
edited Nov 21 '18 at 20:36
answered Nov 21 '18 at 20:23
Mike KinghanMike Kinghan
32.1k867117
32.1k867117
add a comment |
add a comment |
Do this change:
enum class result {
ERROR_BAD_PARAMETER = -3,
ERROR_FILE_NOT_FOUND = -2,
ERROR_GENERAL = -1,
SUCCESS = 0
};
because your enumerated values are in a scope, you no longer have to give them as long a name.
Now your code becomes:
if (MyFunc() != result::SUCCESS) printf("Error!n");
which is a whole 1 character longer than before.
You could also
using my_status_t = result;
if you are tied to my_status_t
as a type name.
As of C++17 there is no way to cleanly avoid the result::
prefix. There is talk about using ERROR_BAD_PARAMETER = result::ERROR_BAD_PARAMETER;
or the like in later versions of C++, but I'm unaware if they are going to get into c++20.
What I'm looking for is the ability to avoid thesomething::
prefix.
– Jeremy Friesner
Nov 21 '18 at 19:21
add a comment |
Do this change:
enum class result {
ERROR_BAD_PARAMETER = -3,
ERROR_FILE_NOT_FOUND = -2,
ERROR_GENERAL = -1,
SUCCESS = 0
};
because your enumerated values are in a scope, you no longer have to give them as long a name.
Now your code becomes:
if (MyFunc() != result::SUCCESS) printf("Error!n");
which is a whole 1 character longer than before.
You could also
using my_status_t = result;
if you are tied to my_status_t
as a type name.
As of C++17 there is no way to cleanly avoid the result::
prefix. There is talk about using ERROR_BAD_PARAMETER = result::ERROR_BAD_PARAMETER;
or the like in later versions of C++, but I'm unaware if they are going to get into c++20.
What I'm looking for is the ability to avoid thesomething::
prefix.
– Jeremy Friesner
Nov 21 '18 at 19:21
add a comment |
Do this change:
enum class result {
ERROR_BAD_PARAMETER = -3,
ERROR_FILE_NOT_FOUND = -2,
ERROR_GENERAL = -1,
SUCCESS = 0
};
because your enumerated values are in a scope, you no longer have to give them as long a name.
Now your code becomes:
if (MyFunc() != result::SUCCESS) printf("Error!n");
which is a whole 1 character longer than before.
You could also
using my_status_t = result;
if you are tied to my_status_t
as a type name.
As of C++17 there is no way to cleanly avoid the result::
prefix. There is talk about using ERROR_BAD_PARAMETER = result::ERROR_BAD_PARAMETER;
or the like in later versions of C++, but I'm unaware if they are going to get into c++20.
Do this change:
enum class result {
ERROR_BAD_PARAMETER = -3,
ERROR_FILE_NOT_FOUND = -2,
ERROR_GENERAL = -1,
SUCCESS = 0
};
because your enumerated values are in a scope, you no longer have to give them as long a name.
Now your code becomes:
if (MyFunc() != result::SUCCESS) printf("Error!n");
which is a whole 1 character longer than before.
You could also
using my_status_t = result;
if you are tied to my_status_t
as a type name.
As of C++17 there is no way to cleanly avoid the result::
prefix. There is talk about using ERROR_BAD_PARAMETER = result::ERROR_BAD_PARAMETER;
or the like in later versions of C++, but I'm unaware if they are going to get into c++20.
edited Nov 21 '18 at 19:32
answered Nov 21 '18 at 18:55
Yakk - Adam NevraumontYakk - Adam Nevraumont
187k20199383
187k20199383
What I'm looking for is the ability to avoid thesomething::
prefix.
– Jeremy Friesner
Nov 21 '18 at 19:21
add a comment |
What I'm looking for is the ability to avoid thesomething::
prefix.
– Jeremy Friesner
Nov 21 '18 at 19:21
What I'm looking for is the ability to avoid the
something::
prefix.– Jeremy Friesner
Nov 21 '18 at 19:21
What I'm looking for is the ability to avoid the
something::
prefix.– Jeremy Friesner
Nov 21 '18 at 19:21
add a comment |
Here's a way:
enum class my_status_t { };
inline constexpr my_status_t RESULT_ERROR_BAD_PARAMETER = my_status_t(-3);
// add other enum values here
Unfortunately, this way you lose some good properties of enum
. Like compiler can warn you if you don't handle a value in a switch (and don't forget to set the underlying type of enum class
, if you have big values).
So I actually don't recommend this way (I better like Yakk's solution), but maybe this answer can help you anyway...
add a comment |
Here's a way:
enum class my_status_t { };
inline constexpr my_status_t RESULT_ERROR_BAD_PARAMETER = my_status_t(-3);
// add other enum values here
Unfortunately, this way you lose some good properties of enum
. Like compiler can warn you if you don't handle a value in a switch (and don't forget to set the underlying type of enum class
, if you have big values).
So I actually don't recommend this way (I better like Yakk's solution), but maybe this answer can help you anyway...
add a comment |
Here's a way:
enum class my_status_t { };
inline constexpr my_status_t RESULT_ERROR_BAD_PARAMETER = my_status_t(-3);
// add other enum values here
Unfortunately, this way you lose some good properties of enum
. Like compiler can warn you if you don't handle a value in a switch (and don't forget to set the underlying type of enum class
, if you have big values).
So I actually don't recommend this way (I better like Yakk's solution), but maybe this answer can help you anyway...
Here's a way:
enum class my_status_t { };
inline constexpr my_status_t RESULT_ERROR_BAD_PARAMETER = my_status_t(-3);
// add other enum values here
Unfortunately, this way you lose some good properties of enum
. Like compiler can warn you if you don't handle a value in a switch (and don't forget to set the underlying type of enum class
, if you have big values).
So I actually don't recommend this way (I better like Yakk's solution), but maybe this answer can help you anyway...
answered Nov 21 '18 at 19:58
gezageza
13.1k32776
13.1k32776
add a comment |
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53415177%2fis-there-a-way-to-specify-an-enum-class-value-without-having-to-type-out-its-sco%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown