typeid(“”) != typeid(const char*)What is the datatype of string literal in C++?How to convert a...
Why are backslashes included in this shell script?
New Site Design!
Would a character with eternal youth be AL-compliant?
Lightning Web Component (LWC) not evaluating if:true from test
typeid("") != typeid(const char*)
What does this circuit symbol mean?
Is it possible to have battery technology that can't be duplicated?
Why is C++ template use not recommended in space/radiated environment?
Do Veracrypt encrypted volumes have any kind of brute force protection?
How to represent jealousy in a cute way?
How can I find out about the game world without meta-influencing it?
Is all-caps blackletter no longer taboo?
What's a opened solder bridge signifies?
Harley Davidson clattering noise from engine, backfire and failure to start
Is there a term for someone whose preferred policies are a mix of Left and Right?
How can religions without a hell discourage evil-doing?
Does every chapter have to "blow the reader away" so to speak?
Should I move out from my current apartment before the contract ends to save more money?
Why is Skinner so awkward in Hot Fuzz?
Why did Robert pick unworthy men for the White Cloaks?
Was the Lonely Mountain, where Smaug lived, a volcano?
Can an escape pod land on Earth from orbit and not be immediately detected?
Is it ethical to cite a reviewer's papers even if they are rather irrelevant?
Someone who is granted access to information but not expected to read it
typeid(“”) != typeid(const char*)
What is the datatype of string literal in C++?How to convert a std::string to const char* or char*?Meaning of 'const' last in a function declaration of a class?What is the difference between const int*, const int * const, and int const *?Best lookup match between const char * and const char (& p)[T_Size]Wrapping cstrings (const char*) to be able to store them into a STL containerReplacing a 32-bit loop counter with 64-bit introduces crazy performance deviationsOverloading operator= or operator[] using const char* and/or stringWhy is 'pure polymorphism' preferable over using RTTI?Why do user-defined string literals and integer literals have different behavior?In C11, string literals as char[], unsigned char[], char* and unsigned char*
.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty{ height:90px;width:728px;box-sizing:border-box;
}
I'm making a C++ library which relies heavily on RTTI (customizable bridge to another language) and is very confused about string literal type.
This is a simple test I made to show the problem:
std::cout << typeid(const char*).name() << std::endl; // PKc
std::cout << std::any("").type().name() << std::endl; // PKc
std::cout << typeid("").name() << std::endl; // A1_c
For me it looks like the first two print the type for const char*, but the last one is an array.
Why do results for std::any("").type() and typeid("") differ? Is there a way to get the first behavior, i.e. make results for string literals consistent (I use type identification to call different type handlers)?
P.S.: tests are done using Clang version 8.0.0-3 (tags/RELEASE_800/final) on Ubuntu 19.04.
c++ c++17 rtti string-literals
add a comment |
I'm making a C++ library which relies heavily on RTTI (customizable bridge to another language) and is very confused about string literal type.
This is a simple test I made to show the problem:
std::cout << typeid(const char*).name() << std::endl; // PKc
std::cout << std::any("").type().name() << std::endl; // PKc
std::cout << typeid("").name() << std::endl; // A1_c
For me it looks like the first two print the type for const char*, but the last one is an array.
Why do results for std::any("").type() and typeid("") differ? Is there a way to get the first behavior, i.e. make results for string literals consistent (I use type identification to call different type handlers)?
P.S.: tests are done using Clang version 8.0.0-3 (tags/RELEASE_800/final) on Ubuntu 19.04.
c++ c++17 rtti string-literals
8
""isn't aconst char*, so they don't have matching types. A""is aconst char[], an array of const char.
– Eljay
9 hours ago
@Eljay Question isn't whether they are or shouldn't be different types. That's a premise of the question. The question is whystd::any("").type()is not array (A1_c).
– eerorika
9 hours ago
3
To add to @Eljay's comment: the 2nd line (std::any) is a pointer because the char array decays to a pointer when it's passed to the constructor.
– Timo
9 hours ago
1
@Timo it's passed by reference, so it doesn't decay when passed.
– Ayxan
8 hours ago
add a comment |
I'm making a C++ library which relies heavily on RTTI (customizable bridge to another language) and is very confused about string literal type.
This is a simple test I made to show the problem:
std::cout << typeid(const char*).name() << std::endl; // PKc
std::cout << std::any("").type().name() << std::endl; // PKc
std::cout << typeid("").name() << std::endl; // A1_c
For me it looks like the first two print the type for const char*, but the last one is an array.
Why do results for std::any("").type() and typeid("") differ? Is there a way to get the first behavior, i.e. make results for string literals consistent (I use type identification to call different type handlers)?
P.S.: tests are done using Clang version 8.0.0-3 (tags/RELEASE_800/final) on Ubuntu 19.04.
c++ c++17 rtti string-literals
I'm making a C++ library which relies heavily on RTTI (customizable bridge to another language) and is very confused about string literal type.
This is a simple test I made to show the problem:
std::cout << typeid(const char*).name() << std::endl; // PKc
std::cout << std::any("").type().name() << std::endl; // PKc
std::cout << typeid("").name() << std::endl; // A1_c
For me it looks like the first two print the type for const char*, but the last one is an array.
Why do results for std::any("").type() and typeid("") differ? Is there a way to get the first behavior, i.e. make results for string literals consistent (I use type identification to call different type handlers)?
P.S.: tests are done using Clang version 8.0.0-3 (tags/RELEASE_800/final) on Ubuntu 19.04.
c++ c++17 rtti string-literals
c++ c++17 rtti string-literals
edited 6 hours ago
Boann
38.1k1291123
38.1k1291123
asked 9 hours ago
valval
5151825
5151825
8
""isn't aconst char*, so they don't have matching types. A""is aconst char[], an array of const char.
– Eljay
9 hours ago
@Eljay Question isn't whether they are or shouldn't be different types. That's a premise of the question. The question is whystd::any("").type()is not array (A1_c).
– eerorika
9 hours ago
3
To add to @Eljay's comment: the 2nd line (std::any) is a pointer because the char array decays to a pointer when it's passed to the constructor.
– Timo
9 hours ago
1
@Timo it's passed by reference, so it doesn't decay when passed.
– Ayxan
8 hours ago
add a comment |
8
""isn't aconst char*, so they don't have matching types. A""is aconst char[], an array of const char.
– Eljay
9 hours ago
@Eljay Question isn't whether they are or shouldn't be different types. That's a premise of the question. The question is whystd::any("").type()is not array (A1_c).
– eerorika
9 hours ago
3
To add to @Eljay's comment: the 2nd line (std::any) is a pointer because the char array decays to a pointer when it's passed to the constructor.
– Timo
9 hours ago
1
@Timo it's passed by reference, so it doesn't decay when passed.
– Ayxan
8 hours ago
8
8
"" isn't a const char*, so they don't have matching types. A "" is a const char[], an array of const char.– Eljay
9 hours ago
"" isn't a const char*, so they don't have matching types. A "" is a const char[], an array of const char.– Eljay
9 hours ago
@Eljay Question isn't whether they are or shouldn't be different types. That's a premise of the question. The question is why
std::any("").type() is not array (A1_c).– eerorika
9 hours ago
@Eljay Question isn't whether they are or shouldn't be different types. That's a premise of the question. The question is why
std::any("").type() is not array (A1_c).– eerorika
9 hours ago
3
3
To add to @Eljay's comment: the 2nd line (
std::any) is a pointer because the char array decays to a pointer when it's passed to the constructor.– Timo
9 hours ago
To add to @Eljay's comment: the 2nd line (
std::any) is a pointer because the char array decays to a pointer when it's passed to the constructor.– Timo
9 hours ago
1
1
@Timo it's passed by reference, so it doesn't decay when passed.
– Ayxan
8 hours ago
@Timo it's passed by reference, so it doesn't decay when passed.
– Ayxan
8 hours ago
add a comment |
3 Answers
3
active
oldest
votes
As others have mentioned, the type of the string literal "" is const char[1], as explained by, e.g., What is the datatype of string literal in C++?.
The type stored in std::any("") is const char* because you are using the following constructor (http://www.eel.is/c++draft/any.cons#8):
// Effects: Constructs an object of type any that contains an object of
// type std::decay_t<T> direct-initialized with std::forward<T>(value).
template< class T>
any( T&& value );
In this case, T is const char(&)[1] (the type of the string literal ""), and thus std::decay_t<const char(&)[1]> will give you const char*, which is why the typeid() of std::any("").type() is the type ID of const char*.
So what I want is to applystd::decaybeforetypeid?
– val
9 hours ago
@val I don't really know what you want to do (not clear from your question), but if you create an object of typestd::decay_t<T>from your object of typeT, this should give you this behavior, similar tostd::anybehavior.
– Holt
9 hours ago
add a comment |
Why do results for
std::any("").type()andtypeid("")differ?
Accroding to the following reference:
template< class ValueType >
any( ValueType&& value );
4) Constructs an object with initial content an object of type
std::decay_t<ValueType>, direct-initialized fromstd::forward<ValueType>(value).
std::decay_t<const char[1]> is const char*.
Here is a quote from FrankHB1989 on the isocpp.org forum, which I think is relevant in understanding std::any, in context of this question:
[
std::any] is even not for "any object". As I have argued before, I have expect the word "any" being short for "any first-class object type" (i.e. cv-unqualified non-array object type), butstd::anyhas additional refinement of CopyConstructible on the value type, so it is actually for "any copyable cv-unqualified non-array object type" instead.
As such
Is there a way to get first behavior, i.e. make results for string literals consistent (I use type identification to call different type handlers)?
There is no way of having std::any of array (you can have std::any of std::array, but string literal is not a std::array), and there is no way of making typeid("") be a pointer. However, you can use std::decay_t<decltype("")> to get the same type as stored in std::any.
add a comment |
It is a common misconception that a string literal has type const char*.
It doesn't. It has type const char[<size + 1>] (plus one for the null terminator).
e.g. "" has type const char[1].
But we often assign a string literal to a const char*, out of convention (and also because otherwise we trigger special rules that result in copying the string).
Furthermore, array name decay rules actually make it quite hard to observe the array-ness of a name in C (and, by extension, C++); that std::any works the way it does is an example of that.
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%2f56564321%2ftypeid-typeidconst-char%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
As others have mentioned, the type of the string literal "" is const char[1], as explained by, e.g., What is the datatype of string literal in C++?.
The type stored in std::any("") is const char* because you are using the following constructor (http://www.eel.is/c++draft/any.cons#8):
// Effects: Constructs an object of type any that contains an object of
// type std::decay_t<T> direct-initialized with std::forward<T>(value).
template< class T>
any( T&& value );
In this case, T is const char(&)[1] (the type of the string literal ""), and thus std::decay_t<const char(&)[1]> will give you const char*, which is why the typeid() of std::any("").type() is the type ID of const char*.
So what I want is to applystd::decaybeforetypeid?
– val
9 hours ago
@val I don't really know what you want to do (not clear from your question), but if you create an object of typestd::decay_t<T>from your object of typeT, this should give you this behavior, similar tostd::anybehavior.
– Holt
9 hours ago
add a comment |
As others have mentioned, the type of the string literal "" is const char[1], as explained by, e.g., What is the datatype of string literal in C++?.
The type stored in std::any("") is const char* because you are using the following constructor (http://www.eel.is/c++draft/any.cons#8):
// Effects: Constructs an object of type any that contains an object of
// type std::decay_t<T> direct-initialized with std::forward<T>(value).
template< class T>
any( T&& value );
In this case, T is const char(&)[1] (the type of the string literal ""), and thus std::decay_t<const char(&)[1]> will give you const char*, which is why the typeid() of std::any("").type() is the type ID of const char*.
So what I want is to applystd::decaybeforetypeid?
– val
9 hours ago
@val I don't really know what you want to do (not clear from your question), but if you create an object of typestd::decay_t<T>from your object of typeT, this should give you this behavior, similar tostd::anybehavior.
– Holt
9 hours ago
add a comment |
As others have mentioned, the type of the string literal "" is const char[1], as explained by, e.g., What is the datatype of string literal in C++?.
The type stored in std::any("") is const char* because you are using the following constructor (http://www.eel.is/c++draft/any.cons#8):
// Effects: Constructs an object of type any that contains an object of
// type std::decay_t<T> direct-initialized with std::forward<T>(value).
template< class T>
any( T&& value );
In this case, T is const char(&)[1] (the type of the string literal ""), and thus std::decay_t<const char(&)[1]> will give you const char*, which is why the typeid() of std::any("").type() is the type ID of const char*.
As others have mentioned, the type of the string literal "" is const char[1], as explained by, e.g., What is the datatype of string literal in C++?.
The type stored in std::any("") is const char* because you are using the following constructor (http://www.eel.is/c++draft/any.cons#8):
// Effects: Constructs an object of type any that contains an object of
// type std::decay_t<T> direct-initialized with std::forward<T>(value).
template< class T>
any( T&& value );
In this case, T is const char(&)[1] (the type of the string literal ""), and thus std::decay_t<const char(&)[1]> will give you const char*, which is why the typeid() of std::any("").type() is the type ID of const char*.
edited 9 hours ago
answered 9 hours ago
HoltHolt
26.9k65598
26.9k65598
So what I want is to applystd::decaybeforetypeid?
– val
9 hours ago
@val I don't really know what you want to do (not clear from your question), but if you create an object of typestd::decay_t<T>from your object of typeT, this should give you this behavior, similar tostd::anybehavior.
– Holt
9 hours ago
add a comment |
So what I want is to applystd::decaybeforetypeid?
– val
9 hours ago
@val I don't really know what you want to do (not clear from your question), but if you create an object of typestd::decay_t<T>from your object of typeT, this should give you this behavior, similar tostd::anybehavior.
– Holt
9 hours ago
So what I want is to apply
std::decay before typeid?– val
9 hours ago
So what I want is to apply
std::decay before typeid?– val
9 hours ago
@val I don't really know what you want to do (not clear from your question), but if you create an object of type
std::decay_t<T> from your object of type T, this should give you this behavior, similar to std::any behavior.– Holt
9 hours ago
@val I don't really know what you want to do (not clear from your question), but if you create an object of type
std::decay_t<T> from your object of type T, this should give you this behavior, similar to std::any behavior.– Holt
9 hours ago
add a comment |
Why do results for
std::any("").type()andtypeid("")differ?
Accroding to the following reference:
template< class ValueType >
any( ValueType&& value );
4) Constructs an object with initial content an object of type
std::decay_t<ValueType>, direct-initialized fromstd::forward<ValueType>(value).
std::decay_t<const char[1]> is const char*.
Here is a quote from FrankHB1989 on the isocpp.org forum, which I think is relevant in understanding std::any, in context of this question:
[
std::any] is even not for "any object". As I have argued before, I have expect the word "any" being short for "any first-class object type" (i.e. cv-unqualified non-array object type), butstd::anyhas additional refinement of CopyConstructible on the value type, so it is actually for "any copyable cv-unqualified non-array object type" instead.
As such
Is there a way to get first behavior, i.e. make results for string literals consistent (I use type identification to call different type handlers)?
There is no way of having std::any of array (you can have std::any of std::array, but string literal is not a std::array), and there is no way of making typeid("") be a pointer. However, you can use std::decay_t<decltype("")> to get the same type as stored in std::any.
add a comment |
Why do results for
std::any("").type()andtypeid("")differ?
Accroding to the following reference:
template< class ValueType >
any( ValueType&& value );
4) Constructs an object with initial content an object of type
std::decay_t<ValueType>, direct-initialized fromstd::forward<ValueType>(value).
std::decay_t<const char[1]> is const char*.
Here is a quote from FrankHB1989 on the isocpp.org forum, which I think is relevant in understanding std::any, in context of this question:
[
std::any] is even not for "any object". As I have argued before, I have expect the word "any" being short for "any first-class object type" (i.e. cv-unqualified non-array object type), butstd::anyhas additional refinement of CopyConstructible on the value type, so it is actually for "any copyable cv-unqualified non-array object type" instead.
As such
Is there a way to get first behavior, i.e. make results for string literals consistent (I use type identification to call different type handlers)?
There is no way of having std::any of array (you can have std::any of std::array, but string literal is not a std::array), and there is no way of making typeid("") be a pointer. However, you can use std::decay_t<decltype("")> to get the same type as stored in std::any.
add a comment |
Why do results for
std::any("").type()andtypeid("")differ?
Accroding to the following reference:
template< class ValueType >
any( ValueType&& value );
4) Constructs an object with initial content an object of type
std::decay_t<ValueType>, direct-initialized fromstd::forward<ValueType>(value).
std::decay_t<const char[1]> is const char*.
Here is a quote from FrankHB1989 on the isocpp.org forum, which I think is relevant in understanding std::any, in context of this question:
[
std::any] is even not for "any object". As I have argued before, I have expect the word "any" being short for "any first-class object type" (i.e. cv-unqualified non-array object type), butstd::anyhas additional refinement of CopyConstructible on the value type, so it is actually for "any copyable cv-unqualified non-array object type" instead.
As such
Is there a way to get first behavior, i.e. make results for string literals consistent (I use type identification to call different type handlers)?
There is no way of having std::any of array (you can have std::any of std::array, but string literal is not a std::array), and there is no way of making typeid("") be a pointer. However, you can use std::decay_t<decltype("")> to get the same type as stored in std::any.
Why do results for
std::any("").type()andtypeid("")differ?
Accroding to the following reference:
template< class ValueType >
any( ValueType&& value );
4) Constructs an object with initial content an object of type
std::decay_t<ValueType>, direct-initialized fromstd::forward<ValueType>(value).
std::decay_t<const char[1]> is const char*.
Here is a quote from FrankHB1989 on the isocpp.org forum, which I think is relevant in understanding std::any, in context of this question:
[
std::any] is even not for "any object". As I have argued before, I have expect the word "any" being short for "any first-class object type" (i.e. cv-unqualified non-array object type), butstd::anyhas additional refinement of CopyConstructible on the value type, so it is actually for "any copyable cv-unqualified non-array object type" instead.
As such
Is there a way to get first behavior, i.e. make results for string literals consistent (I use type identification to call different type handlers)?
There is no way of having std::any of array (you can have std::any of std::array, but string literal is not a std::array), and there is no way of making typeid("") be a pointer. However, you can use std::decay_t<decltype("")> to get the same type as stored in std::any.
edited 9 hours ago
answered 9 hours ago
eerorikaeerorika
94.8k671139
94.8k671139
add a comment |
add a comment |
It is a common misconception that a string literal has type const char*.
It doesn't. It has type const char[<size + 1>] (plus one for the null terminator).
e.g. "" has type const char[1].
But we often assign a string literal to a const char*, out of convention (and also because otherwise we trigger special rules that result in copying the string).
Furthermore, array name decay rules actually make it quite hard to observe the array-ness of a name in C (and, by extension, C++); that std::any works the way it does is an example of that.
add a comment |
It is a common misconception that a string literal has type const char*.
It doesn't. It has type const char[<size + 1>] (plus one for the null terminator).
e.g. "" has type const char[1].
But we often assign a string literal to a const char*, out of convention (and also because otherwise we trigger special rules that result in copying the string).
Furthermore, array name decay rules actually make it quite hard to observe the array-ness of a name in C (and, by extension, C++); that std::any works the way it does is an example of that.
add a comment |
It is a common misconception that a string literal has type const char*.
It doesn't. It has type const char[<size + 1>] (plus one for the null terminator).
e.g. "" has type const char[1].
But we often assign a string literal to a const char*, out of convention (and also because otherwise we trigger special rules that result in copying the string).
Furthermore, array name decay rules actually make it quite hard to observe the array-ness of a name in C (and, by extension, C++); that std::any works the way it does is an example of that.
It is a common misconception that a string literal has type const char*.
It doesn't. It has type const char[<size + 1>] (plus one for the null terminator).
e.g. "" has type const char[1].
But we often assign a string literal to a const char*, out of convention (and also because otherwise we trigger special rules that result in copying the string).
Furthermore, array name decay rules actually make it quite hard to observe the array-ness of a name in C (and, by extension, C++); that std::any works the way it does is an example of that.
answered 9 hours ago
Lightness Races in OrbitLightness Races in Orbit
303k56491845
303k56491845
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%2f56564321%2ftypeid-typeidconst-char%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
8
""isn't aconst char*, so they don't have matching types. A""is aconst char[], an array of const char.– Eljay
9 hours ago
@Eljay Question isn't whether they are or shouldn't be different types. That's a premise of the question. The question is why
std::any("").type()is not array (A1_c).– eerorika
9 hours ago
3
To add to @Eljay's comment: the 2nd line (
std::any) is a pointer because the char array decays to a pointer when it's passed to the constructor.– Timo
9 hours ago
1
@Timo it's passed by reference, so it doesn't decay when passed.
– Ayxan
8 hours ago