Look at this piece of code:
#include <string>
#include <iostream>
using namespace std;
template <typename T, const T& temp>
void g()
{
cout << temp << endl;
}
static const std::string s = "abc";
int main() {
g<string, s>();
}
When I compile this with Visual C++ 2013 November CTP I get:
“error C2970: 'g' : template parameter 'temp' : 's' : an expression involving objects with internal linkage cannot be used as a non-type argument”
However, I read the following in the C++ 14 standard (14.3.2 [temp.arg.nontype]):
“a constant expression (5.19) that designates the address of a complete object with static storage duration and external or internal linkage or”
I interpret this as “constant expression with static storage duration and external linkage” or “constant expression with static storage duration and internal linkage”. In my example above, isn’t the variable s a “constant expression with static storage duration and internal linkage” ?
When I change s to:
std::string s = "abc";
Then it compiles and it works, but isn’t that against the standard because now s is not a “constant expression” anymore.
Can someone shed some light on this? Am I misinterpreting something here?
Replace static
with extern
:
extern const std::string s = "abc";
The reason is that in C++98/C++03, references with internal linkage was not allowed as template argument.
Also note that just removing static
only would not work if const
is there, because const
objects declared at namespace level has internal linkage (unless it is declared extern
). So you need to use extern
as shown above.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With