I can't wrap my head around this problem. I'm trying to use Variadic arguments in a macro, I got it to work in C++11 with the following code:
#define INFO(format,args...) \
{ \
LOG_SEPERATOR; \
std::cout << "FILE: " << __FILE__ << "\n"; \
std::cout << "LINE: " << __LINE__ << "\n"; \
std::cout << "FUNCTION: "<< __func__ << "\n"; \
std::cout << "INFO: \n"; \
ConsoleLog(format,args); \
LOG_SEPERATOR; \
}
\
But in C++20 I cannot use:
#define INFO(format,args...)
The compiler only accepts:
#define INFO(format,...)
Which means I can do this:
#define INFO(...) static int valuesArray[] = __VA_ARGS__
But I cannot do this:
#define INFO(format,...)
{\
valuesArray[] = __VA_ARGS__ ; \
LOG_SEPERATOR; \
std::cout << "FILE: " << __FILE__ << "\n"; \
std::cout << "LINE: " << __LINE__ << "\n"; \
std::cout << "FUNCTION: " << __func__ << "\n"; \
std::cout << "INFO: \n"; \
ConsoleLog(format, valuesArray); \
LOG_SEPERATOR; \
}
I get E0969 - the identifier VA_ARGS can only appear in the replacement lists of variadic macros.
I looked for 2 days now, tried different solutions but I believe I'm way over my head here. I was trying to learn something new but now this just became a puzzle that frustrates me.
Thank you in advance.
#define INFO(format,args...) was never standard C++. It is an extension supported by some compilers.
Since C++20 there is a standard replacement with __VA_OPT__:
#define INFO(format,...) \
{ \
LOG_SEPERATOR; \
std::cout << "FILE: " << __FILE__ << "\n"; \
std::cout << "LINE: " << __LINE__ << "\n"; \
std::cout << "FUNCTION: "<< __func__ << "\n"; \
std::cout << "INFO: \n"; \
ConsoleLog(format __VA_OPT__(,) __VA_ARGS__); \
LOG_SEPERATOR; \
}
There also is std::source_location in C++20 which allows implementing this common type of logging macro with a normal function.
Related
This is the code which gives my desired output using spaces, but I have to perform the task using setw which isn't working as I want(2nd code attached). Help please!
#include<iostream>
#include<iomanip>
using namespace std;
int main()
{
cout << " _________________________________________________________" <<endl ;
cout << " / \\ " <<endl;
cout << " / \\ " <<endl;
cout << " / \\ " <<endl;
cout << " / \\ " <<endl;
cout << " / \\ " <<endl;
cout << " / \\ " <<endl;
return 0;
}
Desired code which doesn't works:
#include<iostream>
#include<iomanip>
using namespace std;
int main()
{
cout << setw(15) << "_________________________________________________________" <<endl ;
cout << setw(14)<< "/ \\ " <<endl;
cout << setw(13)<< "/ \\ " <<endl;
cout << setw(12)<< "/ \\ " <<endl;
cout << setw(11)<<"/ \\ " <<endl;
cout << setw(10)<<"/ \\ " <<endl;
cout << setw(9)<<"/ \\ " <<endl;
return 0;
}
The desired output:
_________________________________________________________
/ \
/ \
/ \
/ \
/ \
/ \
I don't understand what you expect setw to do. What it does is: It sets the width of the output. For example
std::cout << std::setw(5) << 12;
results in output
12
^ ^ 3 spaces
^ ^ total width = 5
This results in the desired output with more spaces in the front (because I was too lazy to count the exact amount, I'll leave that to you):
#include<iostream>
#include<iomanip>
int main()
{
std::cout << std::setw(70) << "_________________________________________________________" << std::endl ;
std::cout << std::setw(71) << "/ \\ " << std::endl;
std::cout << std::setw(72) << "/ \\ " << std::endl;
std::cout << std::setw(73) << "/ \\ " << std::endl;
std::cout << std::setw(74) << "/ \\ " <<std::endl;
std::cout << std::setw(75) << "/ \\ " <<std::endl;
std::cout << std::setw(76) << "/ \\ " <<std::endl;
}
Live Demo
For bonus points you can take a look at std::setfill too. It sets the character that is used to fill the output. For example:
std::cout << std::setfill('x') << std::setw(5) << 12 << std::setfill(' ');
results in output
xxx12
std::setfill is sticky, so you have to reset it when you want the default space fill character again. With a loop your code can be just
std::cout << std::setw(15) << "_" << std::setw(40) << std::setfill('_') << "_" <<endl ;
std::cout << std::setfill(' ');
for (int i=0;i<6;++i){
std::cout << setw(14-i) << "/" << std::setw(43+i*2) << "\\ " <<endl;
}
You probably understood how setw works now, so here is a minimal working code based on your question. Simply add a dedicated character (whitespace or else) as a target for each setw:
#include <iostream>
#include <iomanip>
using namespace std;
int main() {
cout << setw(14) << ' ' << setw(59) << setfill('_') << '_' << setfill(' ') << endl;
cout << setw(14) << '/' << setw(60) << '\\' << endl;
cout << setw(13) << '/' << setw(62) << '\\' << endl;
cout << setw(12) << '/' << setw(64) << '\\' << endl;
cout << setw(11) << '/' << setw(66) << '\\' << endl;
cout << setw(10) << '/' << setw(68) << '\\' << endl;
cout << setw(9) << '/' << setw(70) << '\\' << endl;
return 0;
}
I checked, this code produces exactly your desired output.
I'm new to C++ (not programming in general, just C++) and I'm learning to program in C++ with a subscription to Pluralsight. I'm writing a practice program (a set of games through the computer's console) and I'm stuck on something. While working on a Tic-Tac-Toe game, I want to call a formula for the board that I won't have to rewrite every time. Therefore I defined a set of strings to work for me, but I cannot figure out how to call my user defined formula. I'm not going to post all of the code, because it is very long, but I will show your the parts you need (if a line has "...." on it, that means I removed multiple lines of code to make it fit better for this site). Incase you're wondering, I'm using Microsoft Visual Studio Community 2017 RC and C++14.
HEADER FILE:
#pragma once
#include "targetver.h"
#include <stdio.h>
#include <tchar.h>
#include <iostream>
#include <string>
using namespace std;
MAIN FILE:
....
#define TTTBoard () \
{ \
system("cls"); \
cout << "\n\n Let's play Tic-Tac-Toe!\n\n\n"; \
cout << " A B C " << endl; \
cout << " _______________________ " << endl; \
cout << " | | | |" << endl; \
cout << " 1 | " << PlayerSymA1 << " | " << PlayerSymB1 << " | " << PlayerSymC1 << " |" << endl; \
cout << " |_______|_______|_______|" << endl; \
cout << " | | | |" << endl; \
cout << " 2 | " << PlayerSymA2 << " | " << PlayerSymB2 << " | " << PlayerSymC2 << " |" << endl; \
cout << " |_______|_______|_______|" << endl; \
cout << " | | | |" << endl; \
cout << " 3 | " << PlayerSymA3 << " | " << PlayerSymB3 << " | " << PlayerSymC3 << " |" << endl; \
cout << " |_______|_______|_______|" << endl; \
}
....
int main()
{
//This is where I want to call my TTTBoard formula
}
I tried to call it multiple ways, but nothing worked. Below is what I already tried. I know some of what I tried didn't make complete sense, but I was annoyed that I couldn't get it to work, so I tried it all anyway.
TTTBoard
TTTBoard;
TTTBoard()
TTTBoard();
TTTBoard()
{
}
TTTBoard();
{
}
Thank you in advance for the help!!!
Preprocessor macros are not called. Instead they are expanded, meaning the body of the macro is inserted in place of the macro invocation, with arguments replaced.
So if you have a macro like
#define FOO() { \
bar(); \
}
And then using it
int main()
{
FOO()
}
What the preprocessor creates and the compiler sees is
int main()
{
{ bar(); }
}
The above example also shows how to use a function-like macro.
Lastly, you don't need macros. In a case like yours it makes much more sense to use actual functions. In modern C++ there are seldom much needs for macros.
This is the inefficient, platform dependent code causing the issue.
#define MGE_WARN(X) SetConsoleTextAttribute(hOut, 10); std::cout << "MONSTER (WARNING): ", X << std::endl; SetConsoleTextAttribute(hOut, 1);
Don't ask why or what this is doing - it is meant to print yellow text to the console and does but I am trying to put it in a define now.
Replace
std::cout << "MONSTER (WARNING): ", X << std::endl;
with
std::cout << "MONSTER (WARNING): " << X << std::endl;
// ^^^^^^
Note the change from , to <<.
I am working on the latest revision of the C++ programming language (think it's 5) and run into a problem with g++ version 5.2.
My code is a variation of Small_size template from chap 24.
#include <iostream>
template<int N>
bool is_small ()
{
std::cerr << sizeof(N) << std::endl;
std::cerr << N << std::endl;
return N <= 255;
}
bool ism (int i_n)
{
return i_n <= 255;
}
int main ()
{
std::cout << "hallo welt" << std::endl;
std::cout << 0 << " " << is_small<0> << std::endl;
std::cout << 255 << " " <<is_small<255> << std::endl;
std::cout << -4100000000 << " " << is_small<-4100000000> << std::endl;
std::cout << 256 << " " << is_small<256> << std::endl;
std::cout << 256 << " " << ism(256) << std::endl;
std::cout << 256 << " " << (256 <= 255) << std::endl;
}
When I compile it, it's ok. But when I run the thing, it simply seems to be broken.
[cpp11#hydra src]$ cat ~/bin/g14
#!/bin/bash
g++-52 -std=c++14 "${1}.C" -L$LIBPATH -o "$1"
[cpp11#hydra src]$ g14 konzept_small
[cpp11#hydra src]$ ./konzept_small
hallo welt
0 1
255 1
-4100000000 1
256 1 //1
256 0
256 0
[cpp11#hydra src]$
My problem is that:
the result for 256 and higher is wrong. See comment //1
there is no output of the template code on cerr
I started with a version without the cerr, but got only the wrong template result.
I removed a constexpr from the template, but no change.
So I added as last step the cerr to see whats wrong.
Any ideas?
You are not calling is_small<N>, but just printing out its address. You need to change your code to
std::cout << 0 << " " << is_small<0>() << std::endl;
std::cout << 255 << " " <<is_small<255>() << std::endl;
std::cout << -4100000000 << " " << is_small<-4100000000>() << std::endl;
std::cout << 256 << " " << is_small<256>() << std::endl;
Note the added (). Not sure why you are getting the output you are though, are you sure you are running the same code you posted?
is_small is a function you should add the parenthesis :
change
std::cout << 0 << " " << is_small<0> << std::endl;
to this
std::cout << 0 << " " << is_small<0>() << std::endl;
It worked fine for me with this change
This is the expected output:
COUNT | WORD
------+------
1 | .3
1 | .3.4
1 | 3
2 | 12.34
1 | test1.12.34
3 | this
This is my proper code:
std::cout << "COUNT | WORD" << '\n';
std::cout << "------+------" << '\n';
std::cout << std::setw(4) << "1" << std::setw(3) << '|' << std::setw(3) << ".3" << '\n';
std::cout << std::setw(4) << "1" << std::setw(3) << '|' << std::setw(3) << ".3.4" << '\n';
std::cout << std::setw(4) << "1" << std::setw(3) << '|' << std::setw(3) << "3" << '\n';
std::cout << std::setw(4) << "2" << std::setw(3) << '|' << std::setw(3) << "12.34" << '\n';
std::cout << std::setw(4) << "1" << std::setw(3) << '|' << std::setw(3) << "test1.12.34" << '\n';
std::cout << std::setw(4) << "3" << std::setw(3) << '|' << std::setw(3) << "this" << '\n';
Unfortunately, my ouput's messy the WORD
COUNT | WORD
------+------
1 | .3
1 |.3.4
1 | 3
2 |12.34
1 |test1.12.34
2 |this
Could anyone suggest me a solution for that. Thanks
Instead of having
std::cout << std::setw(4) << "1" << std::setw(3) << '|' << std::setw(3) << ".3" << '\n';
For each line, add a space after the '|' character:
std::cout << std::setw(4) << "1" << std::setw(3) << "| " << std::setw(3) << ".3" << '\n';
Why not this ::
std::cout << "COUNT | WORD" << '\n';
std::cout << "------+------" << '\n';
std::cout << std::setw(4) << "1" << std::setw(3) << '|' << ' ' << ".3" << '\n';
std::cout << std::setw(4) << "1" << std::setw(3) << '|' << ' ' << ".3.4" << '\n';
std::cout << std::setw(4) << "1" << std::setw(3) << '|' << ' ' << "3" << '\n';
std::cout << std::setw(4) << "2" << std::setw(3) << '|' << ' ' << "12.34" << '\n';
std::cout << std::setw(4) << "1" << std::setw(3) << '|' << ' ' << "test1.12.34" << '\n';
std::cout << std::setw(4) << "3" << std::setw(3) << '|' << ' ' << "this" << '\n';
Doing this will set the left hand side filler character.
cout.fill('-');
cout.width(40);
cout<< "LINE1" <<endl;
cout.fill('-');
cout.width(40);
cout<< 3 <<endl;
cout.fill('-');
cout.width(40);
cout<< 3.4 <<endl;
cout.fill('-');
cout.width(40);
cout<< "TEST " << 12.34 <<endl;