A few days ago I asked about regular class interdependency in C++, to which the response was the separation of method declaration and implementation into .cpp and .h filed to eliminate the implementation dependency.
The question now is how to deal with the same interdependency problem just with templated methods, which, as far as I know/read, cannot be strictly implemented (not accounting explicit implementation, which doesn't work in my case) separately between .h and .cpp files.
for example:
class Test_0
{
public:
template<typename T>
static void Testing_0()
{
Test_1::Testing_1();
}
};
class Test_1
{
public:
template<typename T>
static void Testing_1()
{
Test_0::Testing_0();
}
};
Is it possible to then separate the implementation for something like this so that it can actually compile?
Usually we put the dependent codes into another class/function, and these two just call it.
but if you really need, there is also an ugly solution to do that:
template<typename B>
class Test_0_{
template<typename T>
static void Testing_0(){
B::Testing_1<T>();
}
}
template<template<typename>class At>
class Test_1_{
using A = At<Test_1_>;
template<typename T>
static void Testing_1(){
A::Testing_0<T>();
}
}
using Test_1 = Test_1_<Test_0_>;
using Test_0 = Test_0_<Test_1>;
Related
I have a class template that looks like this:
foo.h
template<class C>
class Foo
{
public:
void memberFunc();
};
#include "foo.tpp"
foo.tpp
void Foo::memberFunc()
{
...
}
Ignore the .tpp file, it's just something I do to give the illusion of separating declaration and implementation, obviously that's (kind of) not possible with templates.
My implementation file is much longer in reality, and inside it I have some global scope helper function templates that the member functions use, functions that don't make sense as member functions and that I don't want users of the class to have anything to do with.
template<class C> int helper1() { ... }
template <class C> void helper2() { ... }
template<class C>
void Foo<C>::memberFunc()
{
...
helper1<float>();
...
helper2<C>();
...
}
I do this all the time in .cpp-implementation files and I forgot that when I do it in this fake version of a .cpp file, the declaration and implementation of these little helper functions actually end up in the class template header file. This leads to users of the class template header getting their namespaces cluttered with helper functions that are useless outside the member function implementations.
Obviously I could just put them in a namespace:
namespace foo_helpers
{
template<class C> void helper1() {...}
template<class C> int helper2() {...}
}
But it still leads to outside code being able to use these functions. They only matter to the implementation of the member functions and I want that to be reflected.
When looking for a solution, I learned about the concept of unnamed namespaces. As I understand it, they only allow the current translation unit access to its contents. That sounds like exactly what I need, so I changed the helper functions to this:
namespace
{
template<class C> void helper1() {...}
template<class C> void helper2() {...}
}
But it doesn't work, the functions are still usable from files that include the header.
Is there any way to hide these helper functions from outside code?
I split a generic class into a header and implementation file as follows.
Test.h:
#ifndef MY_DESCRIPTIVE_GUARD_NAME
#define MY_DESCRIPTIVE_GUARD_NAME
template<typename T>
class MyClass
{
T myObj;
public:
MyClass(T& obj);
void set(T& obj);
T get();
}
#include "Test.tpp"
#endif
Test.tpp:
template<typename T>
MyClass<T>::MyClass(T& obj) {
// implementation
}
// etc.
But as I add more methods to MyClass, I keep having to write the same boilerplate:
template<typename T> return-type MyClass<T>::method_name
With dozens of methods (not to mention if I include more template parameters), I'm writing a lot of repeated code. Should I use a macro? Suck it up? Or is there a feature in the language that allows me to package multiple method implementations in one unit, almost as if they were defined in the header file?
I was wondering how we can declare an interface in C++ without using virtual functions. After some internet searching I put together this solution:
#include <type_traits>
using namespace std;
// Definition of a type trait to check if a class defines a member function "bool foo(bool)"
template<typename T, typename = void>
struct has_foo : false_type { };
template<typename T>
struct has_foo<T, typename enable_if<is_same<bool, decltype(std::declval<T>().foo(bool()))>::value, void>::type> : true_type { };
// Definition of a type trait to check if a class defines a member function "void bar()"
template<typename T, typename = void>
struct has_bar : false_type { };
template<typename T>
struct has_bar<T, typename enable_if<is_same<void, decltype(std::declval<T>().bar())>::value, void>::type> : true_type { };
// Class defining the interface
template <typename T>
class Interface{
public:
Interface(){
static_assert(has_foo<T>::value == true, "member function foo not implemented");
static_assert(has_bar<T>::value == true, "member function bar not implemented");
}
};
// Interface implementation
class Implementation:Interface<Implementation>{
public:
// If the following member functions are not declared a compilation error is returned by the compiler
bool foo(bool in){return !in;}
void bar(){}
};
int main(){}
I'm planning to use this design strategy in a project where I will use static polymorphism only.
The C++ standard I will use in the project is C++11.
What do you think are the pros and cons of this approach?
What improvements can be made on the code I proposed?
EDIT 1:
I just realised that inheriting from Interface is not needed. This code could also be used:
class Implementation{
Interface<Implementation> unused;
public:
bool foo(bool in){return !in;}
void bar(){}
};
EDIT 2-3:
One major difference between the static_assert solution (with or without CRTP) and the standard CRTP is that the CRTP does not guarantee that the derived class implements all the interface members. E.g., the following code compiles correctly:
#include <type_traits>
using namespace std;
template< typename T>
class Interface{
public:
bool foo(bool in){
return static_cast<T*>(this)->foo(in);
}
void bar(){
static_cast<T*>(this)->bar();
}
};
class Implementation: public Interface<Implementation>{
public:
// bool foo(bool in){return !in;}
// void bar(){}
};
int main(){}
An error about a missing member function will be returned by the compiler only when the functions foo or bar will be required.
The way I see it, the static_assert solution feels more like an interface declaration than CRTP alone.
An common way to implement static polymorphism is to use CRTP.
With this pattern, you define an templated interface class, whose methods forward to the template:
// Interface
template <typename T>
struct base {
void foo(int arg) {
static_cast<T*>(this)->do_foo(arg);
}
};
You implementation the inherits from the base class and implements the methods:
// Implementation
struct derived : base<derived> {
void do_foo(int arg) {
std::cout << arg << '\n'
}
};
This pattern has the advantage that it looks "feels" a lot like regular runtime polymorphism, and the error messages are generally quite sane. Because all the code is visible to the compiler, everything can be inlined so there's no overhead.
It appears that you want to implement concepts (lite). You may want to read the article before attempting an implementation.
Absent compiler support, you can partially implement this idea. Your static_assert idea is a known way to express interface requirements.
Consider the Sortable example from the link. You can create a class template Sortable, use static_assert to assert all kind of thinks about the template parameter. You explain to your users that they need to implement a certain cet of methods, and to enforce that set is implemented, they need to make use of Sortable<TheirClass> one way or another.
In order to express, right in a function declaration. the idea that your function requires a Sortable, you will have to resort to something like this:
template <typename Container>
auto doSomethingWithSortable (Container&) -> std::enable_if<Implements<Container, Sortable>>::type;
The header file of the class is as follows:
enum class My_Type {
type1,
type2
};
template <int dim>
class My_Class {
public:
My_Class() {};
template <My_Type p_type>
void
func();
}
cpp file:
template <int dim>
template <My_Type p_type>
void
My_Class<dim>::func() {
if (p_type==My_Type::type1) {
...
} else {
...
}
....
}
the call is as follows:
My_Class<2> my_obj;
my_obj.template func<My_Type::type1>();
Everything compiles fine but does not link:
'Undefined symbols for architecture x86_64'
This is because the part of the code is inside a library. Thus I need to explicitly instantiate.
For the class this is obvious:
template class My_Class<2>;
The question is, how do I instantiate the templated function in such a case? Any tricks or workarounds?
p/s/ as you see from enum, I use C++11 if that matters.
p/p/s/ i looked through couple of links, but not sure if I saw the solution.
Funny enough, by trial-and-error I deduced the correct syntax:
template class MyClass<2>;
template void MyClass<2>::func< My_Type::type1>();
template void MyClass<2>::func< My_Type::type2>();
Suppose a header file myheader.hxx defines a class template A in which a non-templated class B is defined (that does not depend on the template parameter of A):
template<class T>
class A {
class B {
// ...
};
};
Is it okay in this case to implement B in myheader.hxx, or do I need to write a separate myheader.cxx to avoid duplicate definitions at link time? Is this case handeled consistently by different compilers?
It's still either a template (or part of template, don't know the ultra-precise definitions) even if it's not the top-level template, so you need to should implement it in the header (technically, it can be in a source file if that's the only place it's used, but that probably defeats the purpose).
Note: if you're not going to implement its member functions inline with the class definition, you need syntax like:
template<typename T>
void A<T>::B::foo(...)
{
// ...
}
Also, because it's come up before, if B happened to have its own template parameter, it would be something like:
template<typename T>
template<typename T2>
void A<T>::B<T2>::foo(...)
{
// ...
}
Not:
template<typename T, typename T2>
void A<T>::B<T2>::foo(...)
{
// ...
}
Or if B didn't but B::foo did, it would be:
template<typename T>
template<typename T2>
// void A<T>::B::foo<T2>(...) // not this apparently
void A<T>::B::foo(...)
{
// ...
}
EDIT: apparently it's foo above instead of foo<T2> for a function, at least with GCC (so almost 100% sure that's standard behavior)...I'm sure some language lawyer will be able to explain why :)
Etc.