cannot declare c++ function without template - c++

i have a relatively small c++ project and i decided to make a Utils header file which would just contain some small helper functions etc. It was all working fine when i was declaring functions that were using a template, then i tried to make a function which didnt need a template, and suddently it doesn't work.
The result i get is a linker error; already defined in (file).obj
I cannot even declare a simple void function, everything without template gives a linker error.
I have NO IDEA whatsoever what could be causing this. Here is the code for the header file... Thanks in advance.
#pragma once
namespace Utils
{
std::string GetActiveWindowTitle()
{
// This doesnt work either, also gives linker error.
return active_window;
}
template<typename T>
void Print(char * value, T printValue)
{
std::cout << value << ": " << printValue << std::endl;
}
template<typename T>
void Print(T printValue)
{
std::cout << "DEBUG: " << printValue << std::endl;
}
void PrintStr(std::string str)
{
// This doesn't work because it doesnt have the template, it gives a linker error
std::cout << "DEBUG: " << str.c_str() << std::endl;
}
}

A function-template is implicitly inline. Thus, when defined in a header file, it doesn't violate ODR (One Definition Rule). For non-template functions in header files, you should either define them as inline, or define them in a separate translation unit.
So, you could do:
#pragma once
namespace Utils
{
inline std::string GetActiveWindowTitle()
{
return active_window;
}
template<typename T>
void Print(char * value, T printValue)
{
std::cout << value << ": " << printValue << std::endl;
}
template<typename T>
void Print(T printValue)
{
std::cout << "DEBUG: " << printValue << std::endl;
}
inline void PrintStr(std::string str)
{
std::cout << "DEBUG: " << str.c_str() << std::endl;
}
}
See Inline keyword vs header definition

If you include your header to more than one cpp, the function will be defined more than once and the linker will give you the error described above. See What is the difference between a definition and a declaration? or What are forward declarations in C++?

Related

Where to put function declaration?

Let's say I'm developing a logging functionality. Inside logging.h I declare the function to be used by the application later on.
// logging.h
#include <string>
namespace logging {
void LogThis(const std::string& text);
}; // namespace logging
Its definition is obviously inside logging.cpp:
// logging.cpp
void logging::LogThis(const std::string& text) {
std::cout << "Log: " << text << '\n';
}
Now lets pretent that my LogThis function's work is split up into some smaller helper functions. They're not part of the logging interface. Let's take a Prettify function as an example.
// logging.cpp
void logging::LogThis(const std::string& text) {
Prettify(text);
std::cout << "Log: " << text << '\n';
}
My question is: Where do I put the function declaration of Prettify? I shouldn't include it in the logging.h header file, because then it can be called by other compilation units and its not part of the interface. So just put it inside logging.cpp instead like this?
// logging.cpp
namespace logging {
void Prettify(std::string& ugly_text);
void LogThis(const std::string& text) {
Prettify(text);
std::cout << "Log: " << text << '\n';
}
void Prettify(std::string& ugly_text) {
// making it pretty...
}
}
I'm looking for some best practices / rules of thumb / opinions on this :) Thanks in advance!
For things that are only needed within the file, I would just place it in an anonymous namespace within the C++ file itself, sort of the modern equivalent of the legacy C static keyword on functions(a):
namespace {
void WeaveMagic(std::string& ugly_text) {
WeaveMoreMagic(ugly_text);
}
void Prettify(std::string& ugly_text) {
WeaveMagic(ugly_text);
}
}
If you place this before any use of the functions, and ensure a strict hierarchy of calls, you can skip the declarations since the definitions provides the required information, as shown above.
Of course, if there are any circular dependencies between multiple anonymous functions (i.e., circular recursion), you will still need to provide declarations:
#include <iostream>
namespace {
int DivThree(int val); // needed to implement AddOne()
int AddOne(int val) {
std::cout << "AddOne " << val << " -> " << (val + 1) << '\n';
if (val > 0) return DivThree(val + 1);
return val;
}
int DivThree(int val) {
std::cout << "DivThree " << val << " -> " << (val / 3) << '\n';
return AddOne(val / 3);
}
}
int main(){
int final = AddOne(18);
std::cout << "Final " << final << '\n';
return 0;
}
And, yes, that's very contrived, but good examples of circular recursion are few and far between :-) The output is:
AddOne 18 -> 19
DivThree 19 -> 6
AddOne 6 -> 7
DivThree 7 -> 2
AddOne 2 -> 3
DivThree 3 -> 1
AddOne 1 -> 2
DivThree 2 -> 0
AddOne 0 -> 1
Final 0
(a) CPP Core Guidline SF.22 actually covers this:
Use an unnamed (anonymous) namespace for all internal/non-exported entities.
Reason: Nothing external can depend on an entity in a nested unnamed namespace. Consider putting every definition in an implementation source file in an unnamed namespace unless that is defining an "external/exported" entity.
An API class and its members can't live in an unnamed namespace; but any "helper" class or function that is defined in an implementation source file should be at an unnamed namespace scope.
If you are operating on functions only, as #paxdiablo have written, you can use anonymous namespace (look at his answer).
I have some C-based habits, so personally I would also see it as static function. But I'm not sure how C++ fanatics will look at it :). static (in this context) makes functions local for compilation unit (logging.cpp), so it cannot be linked from outside.
//logging.cpp
static void Prettify(std::string& ugly);
void LogThis(const std::string& text) {
Prettify(text);
std::cout << "Log: " << text << '\n';
}
static void Prettify(std::string& ugly) { }
However if your logging utility would be object-oriented. I suggest you to use D-pointer and Q-Pointer design pattern (known also as PImpl idiom) - https://en.cppreference.com/w/cpp/language/pimpl .
//logging.h
#include <string>
class loggingImpl;
class logging {
public :
logging();
virtual ~logging();
void LogThis(const std::string& text);
protected :
loggingImpl *impl;
};
//logging.cpp
class loggingImpl
{
public :
loggingImpl(logging *p) : qptr(p) { }
void Prettify(std::string& ugly) { }
//anything what you need and should be hided
// access parent through qptr
protected :
logging *qptr;
};
logging::logging() : impl(new loggingImpl) { }
logging::~logging() { delete impl; }
void logging::LogThis(const std::string& text) {
impl->Prettify(text);
std::cout << "Log: " << text << '\n';
}
As you have written, putting declaration in header file is not proper due to limiting visibility of unused symbols.

Is there a way to get a signature based typeinfo mangled function name using RTTI?

I want to use RTTI and mangled function (pointer) type strings.
Before you categorize this as an XY problem, I'm aware that there are better options to bind functions using polymorphism etc.
This is a purely academical question how to use typeid() properly with function pointers that should differ by their legally overloaded signatures.
If I use the following code, it seems I can retrieve unique typeinfo::name() values for various namespaces/types:
#include <iostream>
#include <typeinfo>
#include <string>
void foo(int) {
}
namespace woozle {
void goozle(int) {}
}
struct bar {
void baz(int) {}
static void boo(int) {}
};
int main() {
std::cout << typeid(&foo).name() << std::endl;
std::cout << typeid(&woozle::goozle).name() << std::endl;
std::cout << typeid(&bar::baz).name() << std::endl;
std::cout << typeid(&bar::boo).name() << std::endl;
}
The output is:
PFviE
PFviE
M3barFviE
PFviE
Perfectly what I expected (I assume the i in the mangled name refers to the parameter signature).
Now I want to have something like this (which is perfectly legal function overloading):
#include <iostream>
#include <typeinfo>
#include <string>
void foo(int) {
}
void foo(std::string) {
}
namespace woozle {
void goozle(int) {}
void goozle(std::string) {}
}
struct bar {
void baz(int) {}
static void boo(int) {}
void baz(std::string) {}
static void boo(std::string) {}
};
int main() {
std::cout << typeid(&foo).name() << std::endl;
std::cout << typeid(&woozle::goozle).name() << std::endl;
std::cout << typeid(&bar::baz).name() << std::endl;
std::cout << typeid(&bar::boo).name() << std::endl;
}
and of course the compiler complains about ambiguity:
main.cpp: In function 'int main()':
main.cpp:24:25: error: address of overloaded function with no contextual type information
std::cout << typeid(&foo).name() << std::endl;
^~~~
main.cpp:25:25: error: address of overloaded function with no contextual type information
std::cout << typeid(&woozle::goozle).name() << std::endl;
^~~~~~~
main.cpp:26:25: error: address of overloaded function with no contextual type information
std::cout << typeid(&bar::baz).name() << std::endl;
^~~~
main.cpp:27:25: error: address of overloaded function with no contextual type information
std::cout << typeid(&bar::boo).name() << std::endl;
^~~~
TL;DR
What is the proper syntax to specify a specific function overload with typeid() (if there is any)?
How can I provide the "contextual type information" that is demanded from the error message?
I'm coming from here in deep thinking mode.
To select a specific function from a set of overloaded functions you can use use the cast notation:
std::cout << typeid(static_cast<void (*)(int)>(foo)).name() << std::endl;
std::cout << typeid(static_cast<void (*)(std::string)>(foo)).name() << std::endl;
std::cout << typeid(static_cast<void (bar::*)(int)>(&bar::baz)).name() << std::endl;
std::cout << typeid(static_cast<void (bar::*)(std::string)>(&bar::baz)).name() << std::endl;
Specifically with typeid though, if you have the type already written down, you can skip the actual function name.
std::cout << typeid(void (*)(int)).name() << std::endl;
is shorter and does the job just as well.

C++ Undefined Reference constructor error?

I am new to C++ and am having difficulties resolving an Undefined Reference problem that I am running into. I am trying to create a test class that takes as input an array into a constructor, and everything seems to work if I have everything located in one file as below:
main.cpp
#include <iostream>
class Test
{
public:
template<typename T,int SIZE>
Test(T (&array)[SIZE]);
};
template<typename T,int SIZE>
Test::Test(T (&array)[SIZE])
{
std::cout << "Array constructor was called" << std::endl;
std::cout << "Size of array is: " << SIZE << std::endl;
}
int main()
{
int myIntArray[10];
Test myTest(myIntArray);
return 0;
}
When I run this example, I get the following output:
Array constructor was called
Size of array is: 10
However, when I break this example up into the following three files:
Test.h
class Test
{
public:
template<typename T,int SIZE>
Test(T (&array)[SIZE]);
};
Test.cpp
#include "Test.h"
#include <iostream>
template<typename T,int SIZE>
Test::Test(T (&array)[SIZE])
{
std::cout << "Array constructor was called" << std::endl;
std::cout << "Size of array is: " << SIZE << std::endl;
}
main.cpp
#include "Test.h"
#include <iostream>
int main()
{
int myIntArray[10];
Test myTest(myIntArray);
return 0;
}
I receive an undefined reference to Test::Test<int, 10>(int (&) [10])'. I am not exactly sure what I am doing incorrectly and am thinking that perhaps I am overlooking something. Any insight would be appreciated. Thank you for the help.
The problem is you are seperating out your template function declaration and template function definition. When you define a template function, your declaration of the function and its definition must be co-located. If not co-located, you should define your template function in a .tpp file and then include that .tpp file in the header file where your template function is declared.
Why is this required? Unlike your normal functions, where the type of the parameters is known beforehand, the compiler loads one version of the template function for every invocation of the function with a different type. So, in your case, when you do,
int main()
{
int myIntArray[10];
Test myTest(myIntArray);
return 0;
}
What the compiler does is, define a function definition,
Test::Test(int (&array)[SIZE])
{
std::cout << "Array constructor was called" << std::endl;
std::cout << "Size of array is: " << SIZE << std::endl;
}
and load this into memory.
However, if the compiler has to do this, it has to have access to the definition of the function when it tries to look over the declaration in the header file. When you put the defintion of the function in a seperate .cpp file, the compiler does not have access to the definition of the function and hence cannot define and load the function into memory based on the user input.
Like I mentioned, if you want to seperate out the implementation from the definition, you can put the definition of the template function in a .tpp(which is a specialized file for template function definitions) file and include that in your .h. Something like this.
Test.h :
class Test
{
public:
template<typename T,int SIZE>
Test(T (&array)[SIZE]);
};
#include "Test.tpp"
Test.tpp
#include <iostream>
template<typename T,int SIZE>
Test::Test(T (&array)[SIZE])
{
std::cout << "Array constructor was called" << std::endl;
std::cout << "Size of array is: " << SIZE << std::endl;
}
main.cpp
#include <iostream>
template<typename T,int SIZE>
Test::Test(T (&array)[SIZE])
{
std::cout << "Array constructor was called" << std::endl;
std::cout << "Size of array is: " << SIZE << std::endl;
}
Hope this helps.
Try this:
main.cpp
#include <iostream>
template<typename T>
class Test
{
public:
Test(T *array, int SIZE)
{
std::cout << "Array constructor was called" << std::endl;
std::cout << "Size of array is: " << SIZE << std::endl;
}
};
Test.h
#include <iostream>
template<typename T>
class Test
{
public:
Test(T *array, int SIZE)
{
std::cout << "Array constructor was called" << std::endl;
std::cout << "Size of array is: " << SIZE << std::endl;
}
};
You probably want to use a std::vector instead of arrays. This way you do not always have to reference the size of the array before you use it. It is much easier to manage.
Additionally, template classes are better off implemented in their header file.

Separate Compilation of template with non-type argument

I'm trying to do separate compilation of my non-type argument template, but I am facing a few problems. My application has a number of opcodes, and each opcode is associated with certain data and functions, many of which are similar and could be defined in the primary template, then the differences can be put into specialized templates.
So here is the original in-line code:
(header)
#include <iostream>
template<int opcode>
class BAR
{
public:
BAR(){};
void foo()
{
std::cout << "BAR<int>::foo()" << std::endl;
}
};
// specialize 1 and 2, otherwise we go with the
// primary definition.
template <>
void BAR<1>::foo()
{
std::cout << "BAR<1>::foo()" << std::endl;
}
template <>
void BAR<2>::foo()
{
std::cout << "BAR<2>::foo()" << std::endl;
}
I have a simple 'main':
int main(int argc, char* argv[])
{
BAR<1> bar_1;
BAR<2> bar_2;
BAR<3> bar_3;
bar_1.foo();
bar_2.foo();
bar_3.foo();
return 0;
}
I managed to put the specializations for '1' and '2' into a cpp file and this is
what I have:
(header)
#include <iostream>
template<int opcode>
class BAR
{
public:
BAR(){};
void foo()
{
std::cout << "BAR<int>::foo()" << std::endl;
}
};
// specialize 1 and 2, otherwise we go with the
// primary definition.
template<> void BAR<1>::foo() ;
template<> void BAR<2>::foo() ;
(cpp)
#include "Foo.h"
#include <iostream>
template<> void BAR<1>::foo()
{
std::cout << "BAR<1>::foo()" << std::endl;
}
template<> void BAR<2>::foo()
{
std::cout << "BAR<2>::foo()" << std::endl;
}
void x()
{
BAR<1> b1;
BAR<2> b2;
b1.foo();
b2.foo();
}
I not real crazy about the x() function, but without this I get unresolved symbols for BAR<1>::foo() & BAR<2>::foo(), if there's a better way, I'd be interested ( MSVC 13 compiler).
Ok so far so good. I really want to put the primary definition of the function foo() into the CPP, but I can't seem to get the syntax right:
template<> void BAR<int>::foo()
{
std::cout << "BAR<int>::foo()" << std::endl;
}
this is not allowed by the compiler, and rightly so I guess, is not
a valid non-type value. So what is the magic words to use to do this?
Many thanks in advance for any help.
dave.

C++ Simple Reflection without Macros: Print Variable Name and Its Value

Is there a non-macro way in C++ of printing a variable name with its value. Here is the macro way:
#define SHOW(a) std::cout << #a << ": " << (a) << std::endl
PS: I'm using Linux and do not need a cross-platform solution
No, C++ does not support reflection and the only way of doing this (as far as I know) are with macros.
You can use dynamic symbols, but then it will only work in shared libraries or executables compiled with the -rdynamic flag. And it will recognize just global variables with default dynamic visibility.
#include <dlfcn.h>
#include <iostream>
int NameMe = 42;
const char *GetName(const void *ptr)
{
Dl_info info;
if (dladdr(ptr, &info))
return info.dli_sname;
else
return NULL;
}
template<typename T>
void Dump(const T &t)
{
const char *name = GetName(&t);
if (name)
std::cout << name;
else
std::cout << "<unknown>";
std::cout << ": " << t << std::endl;
}
int main()
{
int NoName = 33;
Dump(NameMe);
Dump(NoName);
return 0;
}
$ g++ dump.cpp -ldl -rdynamic
$ ./a.out
NameMe: 42
<unknown>: 33
No way.
Without macro, you've to do this:
std::cout <<"a : " << a << std::endl;
No other way.
If you can have all your classes derive from a common ancestor, you can provide a virtual function that accomplishes this. I haven't tried this template, it might not work - some feedback would be appreciated.
struct Reflector
{
virtual void Show() = 0;
};
template<class a, char name[]>
struct ReflectorImpl : public Reflector
{
virtual void Show()
{
std::cout << name << ": " << *this << std::endl;
}
};
class MyClass: public ReflectorImpl<MyClass, "MyClass">
{
};
Yes; in C++17 you can use PFR (in C++17 mode) to get nontrivial levels of non-macro reflection. There are related mechanisms for reflecting the "string-value" of an enum.
See https://github.com/apolukhin/magic_get ;
And https://github.com/Neargye/magic_enum .