Using __LINE__ macro as a template parameter in visual studio - c++

I expected the following code to work, but I received a compile error:
error C2975: 'n' : invalid template argument for 'foo', expected compile-time constant expression
#include <iostream>
using namespace std;
template<int N>
struct foo
{
foo() { cout << N << endl; }
};
int main()
{
foo< __LINE__ > f;
}
Why does this happen? I though __LINE__ would paste in the line number before template instantiation occurred?
If I wanted to do this should I just introduce a static const int to hold the line number or is there a standard solution?

Works for me in VS 2010 10.0.40219.1 SP1Rel and in Ideone
But MSDN mentions problems which result in C2975, if using __LINE__ in template with compiler-option /ZI: MSDN C2975
Edit: Sorry, I linked the german version, here in english

For what it's worth, this is suppose to be valid code. __LINE__ is suppose to behave as if it were:
#define __LINE__ 0
Of course, replacing 0 with the current line number.

#Bob, you are going to love this one!
I was interested in your question so I tried your code. It compiled in g++ but fails with your error in MSVC10. To investigate, I used Google to find out how to see the preprocessor output: you set "Properties | C++ | Preprocessor | Preprocess to a file" to true. And then I compiled again... AND IT WORKED! Turns out if this option is disabled, the compile fails; if it's enabled, the compile works. I suppose MS doesn't bother to generate LINE entries unless the preprocessor output is being captured. Oy va voy!

Related

Function with auto parameter compiles using GCC but does not compile using Visual C++

Please considere the following code-snippet:
#include <iostream>
void print(auto arg) {
std::cout << arg << std::endl;
}
int main() {
print("Hi");
return 0;
}
As you can see here (https://godbolt.org/z/2GSrXs) using GCC the code compiles and runs fine.
As you can see here (https://godbolt.org/z/rtR6w9) using Visual C++ the code does not compile and results in the error message:
<source>(3): error C3533: a parameter cannot have a type that contains 'auto'.
It seems to me that this feature has not jet been implementet in Visual C++?
Additionally I was not able to find the compiler feature in the following list:
https://learn.microsoft.com/en-us/cpp/overview/visual-cpp-language-conformance?view=vs-2019. So I am not sure if the Microsoft developer have the feature on their ToDo List?
Functions receiving auto is a C++20 feature. It must be enabled with /std:latest. However, MSVC only has partial support for this syntax at this time, so not all declaration using this feature will work.
GCC has supported auto in function parameters since early C++14 days as an extension.
You can read more about this C++20 feature reading P1141R2: Yet another approach for constrained declarations
Remaining in C++14 standard, you can use the following lambda instead of your function:
auto print = [](auto arg) {
std::cout << arg << std::endl;
};

How to output c++ type information during compilation

everyone.
I am debugging some problem of type mismatch of a heavily templated class. I would like to know c++ type information during compilation, so I write this:
#pragma message typeinfo(var)
It just do not work.
So I am here asking for some help. I am not sure if it is possible. But I think the compiler must know the type information during compilation.
The preprocessor is not going to help you much itself at compile time. It's job is preprocessing, which happens before compile time.
If the idea is to output type information at compile time then try the following
template <typename...> struct WhichType;
class Something {};
int main() {
WhichType<Something>{};
}
Live example here. When you compile this you should get an error that gives you the type of whatever is inside the templates when trying to instantiate WhichType. This was a neat trick I picked up from Scott Meyers' Effective Modern C++ book. It seems to work perfectly on most mainstream compilers that I have encountered so far.
If you want to get the type information at runtime
#include <iostream>
#include <typeinfo>
using std::cout;
using std::endl;
int main() {
auto integer = int{};
cout << typeid(integer).name() << endl;
}
Note Don't get too comfortable with RTTI (RunTime Type Information) via typeid, C++ also offers several compile time type introspection utilities http://en.cppreference.com/w/cpp/header/type_traits.
I use a type printer helper function, which simply bases on the gcc predefined macro __PRETTY_FUNCTION__. Simply write a templated function which eats everthings and call it from the point where you need to know which type your template expands to. For me it was very helpful to use such a function in case of SFINAE problems and others.
template <typename ... T>
void TemplatePrint(T ... args )
{
std::cout << __PRETTY_FUNCTION__ << std::endl;
}
int main()
{
auto any = std::tuple_cat( std::tuple<int, double>{}, std::tuple<std::string>{} );
TemplatePrint( any );
}
You did not tag your question to a specific compiler, so you maybe need to search for equivalents on other compilers.
On C++ con some year ago a talk was about:
https://baptiste-wicht.com/posts/2016/02/use-templight-and-templar-to-debug-cpp-templates.html. Maybe this will help to get strange template problems solved.

What does `(...)` mean when defining a macro?

I discovered this in the source code for the Unreal Engine 4 and didn't recognize it. The specific instance of it is:
#undef UCLASS
#define UCLASS(...) \
ARadialForceActor_EVENTPARM
I'm a fairly new programmer and this kind of macro is unfamiliar to me. My guess was that it is defining a macro that will take every overloaded version of the function UCLASS (in other words, every instance of a function named UCLASS, regardless of the type and number of parameters) and replace it with the variable ARadialForceActor_EVENTPARM. Is that correct? If not, does anyone know what it means? I tried writing a code snippet to test this, but it returned error: "." may not appear in macro parameter list. I'll include it below, in case I was right about the macro, in which case I would appreciate it if someone could point out where I went wrong in my code:
#include <iostream>
#define foo( . . . ) bar
using namespace std;
int foo() {cout <<54321<<endl;}
int main()
{ bar=12345;
cout<<bar<<endl;
return 0;
}
Your guess of the meaning of #define foo(...) bar is correct. Your error is in thinking that . . . and ... are the same; they are not. ... must be written with no spaces between the dots. If I modify your program to read
#include <iostream>
#define foo(...) bar
using std::cout;
int foo()
{
cout << 54321 << '\n';
}
int main()
{
bar = 12345;
cout << bar << '\n';
return 0;
}
(please take note of other stylistic corrections; future readers of your code will thank you)
then I get error messages consistent with foo() having been replaced with bar in the function definition, as if you had written
int bar
{
cout << 54321 << '\n';
}
which is, in fact, what this tells the preprocessor to do. (The preprocessor, as always, has no understanding of the syntax of the language proper.)
#define FOO(...)
this means your macro can accept variable number of arguments. See here for details.

How can I force a compile error in C++?

I would like to create a compile-time error in my C++ code with a custom error message. I want to do this for a couple of reasons:
to force compilation to fail while I'm working on new features which haven't been implemented yet. (compile time ! TODO reminder)
to create a more readable error when attempting to implement an unsupported template specialization.
I'm sure there is a trick to doing this but I cant find a resource explaining the method. I would wrap the code in a #define of the form COMPILE_FAIL("error message");
Thanks
D
Use #error:
#error "YOUR MESSAGE"
This produces an error from the preprocessor. If you want to detect an error at a later stage (e.g. during template processing), use static_assert (a C++11 feature).
Look into static_assert.
Example:
#include <iostream>
#include <type_traits>
template<typename T>
class matrix {
static_assert(std::is_integral<T>::value, "Can only be integral type");
};
int main() {
matrix<int*> v; //error: static assertion failed: Can only be integral type
}
To force a compiler error (GCC, Clang style):
#error "You ain't finished this yet!"

How to validate that some template does *not* compile for given argument types?

I'm writing a smart ptr template which is intended to be instantiated only for a given base class and its subclasses, which provides boost::shared_ptr-like implicit conversions to variants MyPtr<U> of the template MyPtr<T> has long as the conversion is valid from T* to U* (valid base class and const-compatible).
This was working fine in vs2005, but not with g++ on linux so my colleague changed it there, but doing so it broke the const-correctness.
My problem is that I want to unit test that some conversions are not valid (assign MyPtr<const T> to MyPtr<T> for example), resulting in the file not compiling! But you can't have a file not compiling in the solution...
If there some VS-specific #pragma or some SFINAE trick that could test a given construct is NOT valid and therefore doesn't compile?
Thanks, --DD
You could run the command line compiler, cl, which is pretty easy to set up, and capture its error message output.
No makefile, and hardly any info from the solution/project. Just the include path and a source file. At it's simplest you just need a program that "reverses" the exit code of another program:
#include <sstream>
#include <stdlib.h>
int main(int argc, char *argv[])
{
std::ostringstream command;
for (int n = 1; n < argc; n++)
command << argv[n] << " ";
return (system(command.str().c_str()) == EXIT_SUCCESS)
? EXIT_FAILURE : EXIT_SUCCESS;
}
It simply reconstitutes the arguments passed to it into (omitting its own name) and exits the resulting command line, and then returns success if it fails and failure if it succeeds. That is enough to fool Visual Studio or make.
Technically the reconstituted command line should quote the arguments, but that will only be necessary if you are insane enough to put spaces in your build directory or source file names!
If a given argument (in your case 'const T') would satisfy all the other unit tests except this one you're looking for, isn't it the sign that it would be a perfectly acceptable case?
In other words, if it works, why forbid it?