How do I call a function in a different namespace?
Following code works with gcc (as expected). Your problem must be with something that is not in the question.
#include <iostream>
namespace example
{
void dummy() { std::cout << "Dummy\n"; }
}
namespace buzz
{
void test() { example::dummy(); }
}
int main()
{
buzz::test();
}
Calling functions within namespaces
This does, I believe, exactly what the OP wants, but it's horrible. Every CPP file that includes space.h is going to instantiate bar's 1 and 2 and init. Naming collision hell when the linker tries to sort it all out.
#ifndef SPACE_H
#define SPACE_H
#include <iostream>
namespace space
{
class bar
{
public:
// use your own stuff here. This is for sample use only.
bar(const std::string & str):mStr(str)
{
}
friend std::ostream &operator<<(std::ostream & out, const bar &bq)
{
out << bq.mStr;
return out;
}
private:
std::string mStr;
};
bar *bar1; // consider using std::unique_ptr in place of the raw pointer
bar *bar2;
class Init
{
public:
Init()
{
bar1 = new bar("bar, bar, bar");
bar2 = new bar("barbara anne");
}
virtual ~Init() // std::unique_ptr makes this destructor unnecessary
{
delete bar1;
delete bar2;
}
}
Init init; // init will construct and assign the bars before main
// and destruct and delete the bars when the program exits
}
#endif
static
makes it marginally better static
restricts each bar and init to each including CPP file, but now you have the variables duplicated in each including CPP file, more RAM use and changing one does not change the others.
static bar *bar1;
static bar *bar2;
class Init
{
public:
Init()
{
bar1 = new bar("bar, bar, bar");
bar2 = new bar("barbara anne");
}
virtual ~Init()
{
delete bar1;
delete bar2;
}
};
static Init init;
Another tweak doesn't do exactly what OP wants, but it's close, a lot safer that take 1, and unified across compilation units unlike take 2. extern
instructs the compiler to allow use of bars 1 and 2 without instantiating them, but that means someone has to actually allocate space for them.
extern bar *bar1;
extern bar *bar2;
class Init
{
public:
Init()
{
bar1 = new bar("bar, bar, bar");
bar2 = new bar("barbara anne");
}
virtual ~Init()
{
delete bar1;
delete bar2;
}
};
And a main CPP to demonstrate use
#include <iostream>
#include "space.h"
// allocate the bars and the Init object
space::bar *space::bar1;
space::bar *space::bar2;
space::Init init;
int main()
{
std::cout << *space::bar1 << std::endl;
std::cout << *space::bar2 << std::endl;
return 0;
}
Calling function in a namespace without qualification
According to ISO C++14 standard, at §3.4.2:
When the postfix-expression in a function call is an unqualified-id, other namespaces not considered during the usual unqualified lookup may be searched, and in those namespaces, namespace-scope friend function or function template declarations not otherwise visible may be found. These modifications to the search depend on the types of the arguments (and for template template arguments, the namespace of the template argument).
And following:
For each argument type T in the function call, there is a set of zero or more associated namespaces and a set of zero or more associated classes to be considered. The sets of namespaces and classes is determined entirely by the types of the function arguments..
If
T
is a class type (including unions), its associated classes are: the class itself; the class of which it is a member, if any; and its direct and indirect base classes. Its associated namespaces are the innermost enclosing namespaces of its associated classes.
Actually you can even prevent this from happening by enclosing the function name:
(bar)(a); // doens't compile
while
(B::bar)(a); // does compile
Mind also that this applies only to the innermost namespace, which means that in the following situation you need to qualify the namespace:
namespace B {
namespace C {
struct A {};
}
void bar(const C::A& a) { ... }
}
How to call function A from function B within the same namespace?
I recommend placing the "namespace" inside a function scope. Everything not explicitly public will be naturally private:
var Namespace = (function() {
var self = {};
// Private
var A = function() {
...
};
// Public
self.B = function() {
A();
}
return self;
}());
Namespace.B(); // Works
Namespace.A(); // Doesn't work
Calling a function from another namespace from a string C#
Based on "Sticky bit" answer:
Type thisType = Type.GetType("System.Console");
MethodInfo theMethod = thisType.GetMethod("WriteLine");
theMethod.Invoke(null, new object[1] { "Hello" });
But you have to be careful about method overloads, because then you can get
System.Reflection.AmbiguousMatchException
Also, this aproach isnt the best, and it's a sign of a design problem.
Another thing to take in mind, is using "nameof" operator to tell namespaces names and methods, that's to avoid magic strings.
Applying this on the example i gave:
Type thisType = Type.GetType(nameof(System) + "." + nameof(Console));
MethodInfo theMethod = thisType.GetMethod(nameof(Console.WriteLine));
theMethod.Invoke(null, new object[1] { "Hello" });
Then the caller:
CallMethodFromName(nameof(Console) + "." + nameof(Console.WriteLine), "Hello, world!");
Use a function in different file and different namespace in Visual C++
The problem that compiler does not know about namespace MYSpace
when compiling Source.cpp
.
#include <iostream>
using namespace std;
namespace MyNameSpace
{
int PrintHello();
extern int tempCount;
}
int main()
{
int i;
MyNameSpace::PrintHello();
cout << MyNameSpace::tempCount << endl;
cout << "Hello from main" << endl;
}
But this sample is useless
. It work only because you have only one consumer .cpp
.
You should use .h
file and then include it (PrintFunc.h
) in Source.cpp
and any other .cpp
when you want to use that funtions.
I'll write an example:
Print.h
#pragma once
namespace MyNameSpace
{
int PrintHello();
extern int tempCount;
}
Notice that we dont't use additional includes
and using namespace
here. We would use includes
only to use some classes in functions
interfaces
.using namespace
could "spoil" consumer's .cpp
or .h
.
Print.cpp
#include <iostream>
#include "Print.h"
using namespace std;
int MyNameSpace::tempCount = 111;
int MyNameSpace::PrintHello()
{
cout << "Hello from Source1" << endl;
return 0;
}
Here we can set any include
it will not touch any other files.
And consumer .cpp
:
#include <iostream>
#include "Print.h"
using namespace std;
int main()
{
int i;
MyNameSpace::PrintHello();
cout << MyNameSpace::tempCount << endl;
cout << "Hello from main" << endl;
}
VS specific: #pragma once
and for VS you have to #include "stdafx.h"
at first line in any .cpp
calling a function from a class inside a namespace?
I was able to get this working using the following methods.
Create a new folder in VSCode. I named it
SO_66629443_20210315
and put it in my X:\test folderAdd the 3 files.
Fix the missing includes.
legeplads.cpp
requires#include <iostream>
and#include "frileg.h"
andmain.cpp
requires#include "frileg.h"
Modify
main.cpp
to use the frileg namespace when constructing a; usefrileg::legeplads a;
instead oflegeplads a;
So at this point the files look like:
main.cpp
#include "frileg.h"
int main()
{
frileg::legeplads a;
a.x = 1;
a.y = 2;
a.z = 3;
a.print();
return 0;
}
legeplads.cpp
#include "frileg.h"
#include <iostream>
void frileg::legeplads::print()
{
std::cout << "pos: {" << x << ", " << y << ", " << z << "}" << std::endl;
}
frileg.h
namespace frileg
{
class legeplads
{
public:
int x;
int y;
int z;
void print();
};
}
- Modify
tasks.json
to compile more than 1 file as the documentation tells you here: https://code.visualstudio.com/docs/cpp/config-mingw#_modifying-tasksjson
so the tasks.json
file looks exactly like:
{
"tasks": [
{
"type": "cppbuild",
"label": "C/C++: g++.exe build active file",
"command": "C:\\msys64\\mingw64\\bin\\g++.exe",
"args": [
"-g",
"${workspaceFolder}\\*.cpp",
"-o",
"${fileDirname}\\${fileBasenameNoExtension}.exe"
],
"options": {
"cwd": "C:\\msys64\\mingw64\\bin"
},
"problemMatcher": [
"$gcc"
],
"group": {
"kind": "build",
"isDefault": true
},
"detail": "Task generated by Debugger."
}
],
"version": "2.0.0"
}
Note that I am using msys2 for my mingw installation. I installed that using these instructions: https://www.msys2.org/
And finally executing the program in VSCode looked like this:
PS X:\test\SO_66629443_20210315> & 'c:\Users\dresc\.vscode\extensions\ms-vscode.cpptools-1.2.2\debugAdapters\bin\WindowsDebugLauncher.exe' '--stdin=Microsoft-MIEngine-In-gtfgey3y.olb' '--stdout=Microsoft-MIEngine-Out-l2sggqju.oz3' '--stderr=Microsoft-MIEngine-Error-zgahgwi3.zwy' '--pid=Microsoft-MIEngine-Pid-0mc3zqbv.bqm' '--dbgExe=C:\msys64\mingw64\bin\gdb.exe' '--interpreter=mi'
pos: {1, 2, 3}
Using functions from global namespace in a namespace
Is it a good practice, or there is a more elegant solution?
IMHO, you can use it with third party library. It is clear and expressive enough. It would be better if you could write:
void World() {
::f(100); // f from global namespace
::f(100, 200); // f from global namespace
f(100, 200, 300); // f NOT from global namespace
}
because then it is clearly visible which function is and which is not from the global namespace but this solution does not work for you since you cannot modify implementation of World
function.
Can I only import
f(int)
and notf(int, int)
?
Yes. You can do the following in order to import only f(int)
function:
void f(int) {}
namespace Hello {
using ::f; // only void f(int) is defined before this line
// therefore, it is the only overload being imported to the Hello namespace
}
void f(int,int) {}
Demo
UPDATE
If you want to import only one overload of an operator<<
, not an ordinary function, then you could wrap each overload in a separate namespace like this:
namespace XX {
struct X {
int x;
};
std::ostream& operator<<(std::ostream& os, X const& x) {
return os;
}
}
namespace YY {
std::ostream& operator<<(std::ostream& os, Y const& y) {
return os;
}
struct Y {
double y;
};
}
namespace Hello {
using ::XX::X;
using ::XX::operator<<;
using ::YY::Y;
}
Check it out live.
Related Topics
How to Count How Many Values Per Level in a Given Factor
How to Specify Lib Directory When Installing Development Version R Packages from Github Repository
Does R Leverage Simd When Doing Vectorized Calculations
How to Change the Na Color from Gray to White in a Ggplot Choropleth Map
Sort a Factor Based on Value in One or More Other Columns
How to Call External R Script from R Markdown (.Rmd) in Rstudio
How to Manually Create a Dendrogram (Or "Hclust") Object? (In R)
Conditional 'Echo' (Or Eval or Include) in Rmarkdown Chunks
Why Is Foreach() %Do% Sometimes Slower Than For
Change Internal Function of a Package
Replace Na with 0 in a Data Frame Column
How to Include Rmarkdown File in R Package
Initialize an Empty Tibble with Column Names and 0 Rows
Replace Na with Zero in Dplyr Without Using List()
Excel Cell Coloring Using Xlsx