Okay so I was thinking, wasn't there a way to get around having an entire template class declared in a .h file, and maybe make use of a cpp file to avoid some include errors? I do rely on forward declarations every now and then so, having implementations in a cpp file is ideal in my situation. Now was there a way to do this, or am I misremembering things? Was it like, void ClassName<tType>::FunctionName for functions, and then you forward declare the various class types to make sure each class is generated?
#Not quite finding the resource I had in mind
21 messages · Page 1 of 1 (latest)
When your question is answered use !solved to mark the question as resolved.
Remember to ask specific questions, provide necessary details, and reduce your question to its simplest form. For tips on how to ask a good question use !howto ask.
What do you mean when yousay you rely on forward declarations?
It means what it means. When there is no function-body, just a head, you're just using a pointer, which means that you can just forward declare some stuff.
Instead of including it.
a.h in b.cpp and b.h in a.cpp is not a circular include.
You can redeclare a member function of template class for a particular template specialization. And only if all template parameters are specialized can you then implement that function in a cpp file.
Do you have an example of what that would look like?
I do. I actually did this recently. But I'm at work and the code is on my home computer, if you don't mind waiting a few hours.
Plus, I'm on mobile so I really can't type it out right now
Well, I'm interested, it'd be interesting to see, maybe some memories of what I was thinking of will come back.
@fervent cobalt
// Example.h
#pragma once
template <class T>
void foo(T val);
void test(char c);
// Example.cpp
#include "Example.h"
#include <iostream>
void test(char c) { foo(c); }
// Works in main.cpp
template <>
void foo(signed val) {
std::cout << "Signed: " << val << std::endl;
}
// Works in main.cpp
template <>
void foo(unsigned val) {
std::cout << "Unsigned: " << val << std::endl;
}
// Only defines foo for this source file.
template <class T>
void foo(T val) {
std::cout << "Template: " << val << std::endl;
}
// main.cpp
#include <iostream>
#include "Example.h"
int main() {
foo(3);
foo(3u);
// foo('3'); // Linker error: unresolved external foo<char>
test('3');
}
Output:
Signed: 3
Unsigned: 3
Template: 3
This is interesting, but the functions are not contained within a class. Maybe that just isn't possible to do after all?
not sure if I fully understand the situation, but I think you just need to instantiate the class in the .cpp
a common problem then is that you need to instantiate for all the specific Ts you are going to use
if you don't know all the types, I think you need a different solution (type erasure)
// something.hpp
template<typename T>
struct Something {
template<typename U>
T test(U&&) const;
};
#include "something.inl"
``````cpp
// something.inl
template<typename T>
template<typename U>
T Something::test(U&& value) const {
return static_cast<T>(std::forward<U>(value)); // e.g.
}
I've read about std forward did, but I didn't fully understand it really.
that's not important, i meant to demonstrate how some people split templates into declarations and definitions by making another file
I imagine two ways you'd try to do this. header-guards around the template class, and headerguards around both the class template and the include. I think both would result in similar issues as just having the whole implementation in something.hpp.
If you have something.h in b.h, and b.h in somethhing.h, when you include something.h in b.h, you also include something.inl in b.h. So at first glance what you did here does not solve the problem but moves it around.
Could be wrong, but for now I don't think I am.
It works the same for member functions