std::variant declaration is not found by compiler - c++

What I am trying to do is very simple, I need to create a vector that can hold different types of data. So I read about std::variant and am trying to use it, however, when declaring my "std::vector< std::variant< typenames > >", the compiler complains about not finding the declaration for variant<> even though I included the variant library.
(errors are "use of undeclared identifier variant" with implicit namespace, and "no member named 'variant' in namespace 'std'" with explicit namespace). My Clang version is 11, and I am using c++17, so I don't know what I could be missing here. For what it's worth, I am currently using VScode 1.53. This is my c_cpp_properties.json :
{
"configurations": [
{
"name": "Linux",
"includePath": [
"${workspaceFolder}/**",
"/usr/include/"
],
"defines": [],
"compilerPath": "/usr/bin/clang",
"cStandard": "c17",
"cppStandard": "c++17",
"intelliSenseMode": "linux-clang-x64"
}
],
"version": 4
}
I have tried also changing the cpp version in the default GUI provided by vscode to manage the cpp compiler, that made no difference.
What I am doing is something similar to this:
#include <vector>
#include <variant>
struct c {
std::vector< std::variant<glm::vec2, glm::vec3, glm::vec4>> v;
};
Does anyone have any idea why this is happening, or had this problem before and knows a solution?
Solution:
Turns out specifying the cpp standard on the file c_cpp_properties.json is not enough. You have to add "-std=c++17" to tasks.json as well, after "-g", like this:
{
"tasks": [
{
"type": "cppbuild",
"label": "C/C++: clang++ build active file",
"command": "/usr/bin/clang++",
"args": [
"-g",
"-std=c++17",
...

I am not a Clang expert, but try using the option -std=c++17.
According to this the default seems to be C++98.

This appears to work fine in MSVC:
#include <variant>
struct c {
std::vector< std::variant<int, float>> v;
}
It seems like the compiler might be throwing a fit about the template type nesting(wild guess here). Maybe try the following as a workaround:
#include <variant>
struct c {
typedef std::variant< int, float> TwoPartVariant;
std::vector< TwoPartVariant> v;
};

Related

How can I solve VSCode / g++ not recognising default include files? [duplicate]

This question already has answers here:
Why is "using namespace std;" considered bad practice?
(41 answers)
Closed 9 months ago.
I am very new to coding in C++ and have little to no experience at all. My problem is: I wanted to use strings so i added #include to the includes in my code but VSCode tells me identifier "string" is undefinedC/C++(20). What I have done is added and modified a c_cpp_properties.json file vor VSCode:
{
"configurations": [
{
"name": "Linux",
"includePath": [
"${workspaceFolder}/**",
"/usr/include/**"
],
"defines": [],
"compilerPath": "/usr/bin/gcc",
"cStandard": "gnu17",
"cppStandard": "gnu++14",
"intelliSenseMode": "linux-gcc-x64"
}
],
"version": 4
}
But that didn't solve the problem. Also, I have made sure that C++ is installed, including the g++ compiler. In VSCode I am using following C++ plugins / addons: C/C++ and C/C++ Project Generator (which I don't really use).
This is the relevant part of my code:
#include <iostream>
#include <string>
int main(int argc, char *argv[])
{
string s;
return 0;
}
And this is the error log / debug message:
g++ -std=c++17 -Wall -Wextra -g -Iinc -c src/main.cpp -o src/main.o
src/main.cpp: In function ‘int main(int, char**)’:
src/main.cpp:30:2: error: ‘string’ was not declared in this scope
30 | string s;
| ^~~~~~
src/main.cpp:30:2: note: suggested alternatives:
In file included from /usr/include/c++/9/iosfwd:39,
from /usr/include/c++/9/ios:38,
from /usr/include/c++/9/ostream:38,
from /usr/include/c++/9/iostream:39,
from src/main.cpp:1:
/usr/include/c++/9/bits/stringfwd.h:79:33: note: ‘std::string’
79 | typedef basic_string<char> string;
| ^~~~~~
In file included from /usr/include/c++/9/bits/locale_classes.h:40,
from /usr/include/c++/9/bits/ios_base.h:41,
from /usr/include/c++/9/ios:42,
from /usr/include/c++/9/ostream:38,
from /usr/include/c++/9/iostream:39,
from src/main.cpp:1:
/usr/include/c++/9/string:67:11: note: ‘std::pmr::string’
67 | using string = basic_string<char>;
| ^~~~~~
Solution: Replace string s; with std::string s;.
C++ strings are "hidden" inside the std namespace. The compiler doesn't recognize string because of that.
You could either include the entire std namespace:
using namespace std;
Do this for specifically strings and nothing else:
using std::string;
or type std::string instead of string when initializing strings. The C++ Standard Library is in the compiler's include path by default, you don't need to do anything extra to be able to use its headers.

Unable to compile C++ program on a macosx: error: unknown type name 'constexpr'

I am trying to compile the below program. However it's giving me the error: unknown type name 'constexpr' error. What should I do?
Code:
//this is model.cpp. battery.cpp and load.cpp are two secondary files
#include "load.h"
#include "battery.h"
//compile time constants - Settings
constexpr int intervals = 96;
constexpr float e_min = 0.001;
constexpr int max_iters = 100;
constexpr int nloads = 10;
constexpr int nbat = 10;
struct devices
{
load loadDevices[nloads];
battery batteryDevices[nbat];
};
int main()
{
//Initialization of the model
devices devices1;
return 0;
}
I get the same error on each line where constexpr is used.
error: unknown type name 'constexpr'
constexpr int intervals = 96;
My C/C++ configurations .json file is as follows:
{
"configurations": [
{
"name": "Mac",
"includePath": [
"${workspaceFolder}/**"
],
"defines": [],
"macFrameworkPath": [],
"compilerPath": "/usr/local/bin/gcc-11",
"cStandard": "gnu17",
"cppStandard": "gnu++17",
"intelliSenseMode": "macos-gcc-x64"
}
],
"version": 4
}
System: MACOSX
IDE: VSCode
Compiling on Mac's Terminal using g++
compilation command: g++ model.cpp battery.cpp load.cpp
That json config is not used if you are calling the compiler directly from the command line. In that case you have to specify every option yourself:
g++ -std=gnu++17 -Wall -Werror model.cpp battery.cpp load.cpp
I just added -Wall -Werror for good measure, you should never compile your code without them.
Without the -std option the compiler uses an older version of the C++ standard that does not have constexpr.

Coroutine debugging in c++

I am trying to test out the coroutine feature of c++20 I have included the necessary flags, but when I #include <coroutine> I get the following error:
cannot open source file "coroutine". I'm sure it's a stupid error!
Code:
// lazyGenerator.cpp
#include <iostream>
#include <vector>
#include <coroutine> // <---- the immediate error, which causes generator and co-yield not to work
using namespace std;
generator<int> generatorForNumbers(int begin, int inc = 1) {
for (int i = begin;; i += inc) {
co_yield i;
}
}
int main() {
std::cout << std::endl;
const auto numbers= generatorForNumbers(-10); // (2)
for (int i= 1; i <= 20; ++i) std::cout << numbers << " "; // (4)
std::cout << "\n\n";
for (auto n: generatorForNumbers(0, 5)) std::cout << n << " "; // (3)
std::cout << "\n\n";
}
In tasks.json
{
// See https://go.microsoft.com/fwlink/?LinkId=733558
// for the documentation about the tasks.json format
"version": "2.0.0",
"tasks": [
{
"type": "shell",
"label": "clang++ build active file",
"command": "/usr/bin/clang++",
"args": [
"-std=c++2a", // <---- changed from -std==c++21 by suggestion
"-fcoroutines",
"-stdlib=libc++",
"-g",
"${file}",
"-o",
"${fileDirname}/${fileBasenameNoExtension}"
],
"options": {
"cwd": "${workspaceFolder}"
},
"problemMatcher": [
"$gcc"
],
"group": {
"kind": "build",
"isDefault": true
}
}
]
}
Result of running clang++ -v
clang version 11.1.0
Target: x86_64-apple-darwin20.3.0
Thread model: posix
InstalledDir: /usr/local/opt/llvm/bin
Error for coroutine with c++2a flag
/Users/lukeanglin/Desktop/C++/debug/hello_world.cpp:5:10: fatal error: 'coroutine' file not found
#include <coroutine>
^~~~~~~~~~~
1 error generated.
The terminal process "/bin/zsh '-c', '/usr/bin/clang++ -std=c++2a -stdlib=libc++ -g /Users/lukeanglin/Desktop/C++/debug/hello_world.cpp -o /Users/lukeanglin/Desktop/C++/debug/hello_world'" terminated with exit code: 1.
Error if I run the c++20 flag:
error: invalid value 'c++20' in '-std=c++20'
note: use 'c++98' or 'c++03' for 'ISO C++ 1998 with amendments' standard
note: use 'gnu++98' or 'gnu++03' for 'ISO C++ 1998 with amendments and GNU extensions' standard
note: use 'c++11' for 'ISO C++ 2011 with amendments' standard
note: use 'gnu++11' for 'ISO C++ 2011 with amendments and GNU extensions' standard
note: use 'c++14' for 'ISO C++ 2014 with amendments' standard
note: use 'gnu++14' for 'ISO C++ 2014 with amendments and GNU extensions' standard
note: use 'c++17' for 'ISO C++ 2017 with amendments' standard
note: use 'gnu++17' for 'ISO C++ 2017 with amendments and GNU extensions' standard
note: use 'c++2a' for 'Working draft for ISO C++ 2020' standard
note: use 'gnu++2a' for 'Working draft for ISO C++ 2020 with GNU extensions' standard
The terminal process "/bin/zsh '-c', '/usr/bin/clang++ -std=c++20 -stdlib=libc++ -g /Users/lukeanglin/Desktop/C++/debug/hello_world.cpp -o /Users/lukeanglin/Desktop/C++/debug/hello_world'" terminated with exit code: 1.
At the time of writing, the current release of Clang does not fully implement the coroutines as described here.
However, the last release support a old coroutine TS that has been superseded since C++20. If you want just to play with coroutines temporary, you can enable it by using the compilation flags -std=c++20 -stdlib=libc++ and by replacing your include with #include <experimental/coroutine>. I you want a non-experimental version, you need to wait.

Use sqlite3 in vscode for c++(undefined reference to `xxx')(I have use -lsqlite3)

I'm going crazy for this problem. I downloaded the source code and pre-compiled files of sqlite3 according to the tutorial, and used vs to compile, got the sqlite3.lib and sqlite3.exp files, and put it in the C: \ sql folder. Then I created the project in vscode, and put sqlite3.h in the root directory of the project, and created the following test code.
#include "sqlite3.h"
#include <stdio.h>
#include <stdlib.h>
#pragma warning(disable : 4996)
#pragma comment(lib, "c:\\sql\\sqlite3.lib")
int main() {
sqlite3 *db = NULL;
char *zErrMsg = 0;
int rc;
rc = sqlite3_open("Student.db", &db);
if (rc) {
fprintf(stderr, "Can't open database: %s\n", sqlite3_errmsg(db));
sqlite3_close(db);
exit(1);
} else
printf("open mydata successfully!\n");
sqlite3_close(db);
system("pause");
return 0;
}
My tasks.json
{
// See https://go.microsoft.com/fwlink/?LinkId=733558
// for the documentation about the tasks.json format
"version": "2.0.0",
"tasks": [
{
"label": "gdb",
"type": "shell",
"command": "g++",
"args": [
"${file}",
"-o",
"${fileDirname}\\${fileBasenameNoExtension}.exe",
"-LC:\\sql",
// "${fileDirname}\\src\\Account.cpp",
// "${fileDirname}\\src\\Person.cpp",
// "${fileDirname}\\src\\Date.cpp",
// "${fileDirname}\\src\\System.cpp",
// "${fileDirname}\\src\\Administrator.cpp",
"-lsqlite3",
],
"group": {
"kind": "build",
"isDefault": true
}
}
]
}
But no matter how I modify the tasks.json file, I still get the following result. I am really too lost. Can anyone help me how to solve this problem?
c:/mingw/bin/../lib/gcc/mingw32/9.2.0/../../../../mingw32/bin/ld.exe: C:\Users\Drew\AppData\Local\Temp\ccUXavQh.o:test.cpp:(.text+0x2e): undefined reference to `sqlite3_open'
c:/mingw/bin/../lib/gcc/mingw32/9.2.0/../../../../mingw32/bin/ld.exe: C:\Users\Drew\AppData\Local\Temp\ccUXavQh.o:test.cpp:(.text+0x45): undefined reference to `sqlite3_errmsg'
c:/mingw/bin/../lib/gcc/mingw32/9.2.0/../../../../mingw32/bin/ld.exe: C:\Users\Drew\AppData\Local\Temp\ccUXavQh.o:test.cpp:(.text+0x6d): undefined reference to `sqlite3_close'
c:/mingw/bin/../lib/gcc/mingw32/9.2.0/../../../../mingw32/bin/ld.exe: C:\Users\Drew\AppData\Local\Temp\ccUXavQh.o:test.cpp:(.text+0x91): undefined reference to `sqlite3_close'
collect2.exe: error: ld returned 1 exit status
I personally download the sqlite-amalgamation source and compile it as a regular source file. SQLite made it very easy and you should have no problem https://www.sqlite.org/download.html
I don't mess with static/dynamic libs when I don't need to. The problem may occur because of which compiler compiled the library (ie ms compiler, mingw, clang, etc). There's a chance you may be mixing them causing the error. I suspect the precompile one is using ms compiler. From memory clang works with libs compiled with ms compiler (clang depends on it). mingw doesn't depend on it and won't use ms compiled libs

Compiling C++ in VSCode gives me an undefined reference

Normally I use VS19 for C++ programming, but I wanted to try if it works on VSCode on my Macbook, so I wrote a real simple program:
main
#include <iostream>
#include "test.hpp"
using namespace std;
int main()
{
testfile obj(5);
cout << "main.cpp" << endl;
obj.output();
return 0;
}
class header (.hpp)
#pragma once
using namespace std;
class testfile
{
private:
int i;
public:
testfile(int in) : i(in) {}
void output();
};
class file (.cpp)
#include "test.hpp"
#include <iostream>
using namespace std;
void testfile::output()
{
cout << i << endl;
}
I know I could write the little output in the header, but I want to try if it works if the code is split up into many different files. I get the following error:
(PATH)..\Temp\ccITg6NM.o:main.cpp:(.text+0x48): undefined reference to
`testfile::output()' collect2.exe: error: ld returned 1 exit status
The same goes for my windows laptop. I ran the exact same code on Visual Studio and it worked perfectly fine. I tried googling the error but tbh, I didn't got anything out of it...
I run VSCode with C/C++ intellisense and the compile & run plugin.
It's pretty tricky... I'm not sure but the linker maybe ignore the implementation of testfile::output() in test.cpp because the header test.hpp include implementation of constructor testfile::testfile(int in).
I actually cannot reproduce the problem, try this :
test.hpp
#pragma once
using namespace std;
class testfile
{
private:
int i;
public:
testfile(int in);
void output();
};
test.cpp
#include "test.hpp"
#include <iostream>
using namespace std;
testfile::testfile(int in) : i(in) {}
void testfile::output()
{
cout << i << endl;
}
I think it is better that all implementation are in *.cpp file like above.
EDIT :
I use g++ for compiling those files(I'm sorry I don't have VScode environment).
command line(correct) :
g++ main.cpp test.cpp -o out
output :
D:\workspace\test2\test2>out
main.cpp
5
command line(incorrect, test.cpp is missing) :
g++ main.cpp -o out
output :
${User}\AppData\Local\Temp\ccYKJ92L.o:main.cpp:(.text+0x1a): undefined reference to `testfile::testfile(int)'
${User}\AppData\Local\Temp\ccYKJ92L.o:main.cpp:(.text+0x48): undefined reference to `testfile::output()'
collect2.exe: error: ld returned 1 exit status
command line(incorrect, main.cpp is missing) :
g++ test.cpp -o out
output :
C:/Program Files/mingw-w64/x86_64-8.1.0-posix-seh-rt_v6-rev0/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/8.1.0/../../../../x86_64-w64-mingw32/lib/../lib/libmingw32.a(lib64_libmingw32_a-crt0_c.o):crt0_c.c:(.text.startup+0x2e): undefined reference to `WinMain'
collect2.exe: error: ld returned 1 exit status
EDIT2 :
I installed VSCode although I use windows, I think I figured out why these type of error occur.
You might use F6 command for build the sources w/ C/C++ Compile Run, but the F6 command is applied only for a file which is currently selected and showed on editor. You select main.cpp then linker cannot find method of class testfile, otherwise select test.cpp then linker cannot find entry point(main) of project.
So if you want to build correctly, you must make kind of build script(makefile, json, something).
If you type Ctrl+Shift+P, you can fild Tasks: Configure task tab. Click them and configure your setting(host OS, compiler, ...) It would gives you default tasks.json file with minimal form.
I use this json file(Windows, mingw(gcc for windows))
tasks.json
{
"version": "2.0.0",
"command": "g++",
// compiles and links with debugger information
"args": ["-g", "-o", "out.exe", "main.cpp", "test.cpp"],
}
Ctrl+Shift+B (build using above json), then its output:
running command> g++ -g -o out.exe main.cpp test.cpp
It builds out.exe file successfully.
If you want to debug or run, use F5 or Ctrl+F5 or Debug tab on the top menu bar, then its output on debug console:
main.cpp
5
Debug or run step refers to launch.json file like build step refers to tasks.json file.
for reference, launch.json :
{
"version": "0.2.0",
"configurations": [
{
"name": "(Windows)build test",
"type": "cppvsdbg",
"request": "launch",
"program": "${workspaceFolder}/out.exe",
"args": [],
"stopAtEntry": false,
"cwd": "${workspaceFolder}",
"environment": [],
"externalConsole": false
}
]
}
Concolusionally it's not problem of source.
For further infomation refer to this post :
How do I set up Visual Studio Code to compile C++ code?