I'm trying to define a template class that has some operations on a type.
The method ToString should be implemented to call the ToString in the namespace of whatever type the Tools template class has been instantiated with.
namespace X
{
class SomeType
{
};
std::wstring ToString(SomeType)
{
// ...
}
}
template<class T>
class Tools
{
static auto ToString(T& t)
{
return ToString(t);
}
}
I get an error in the Tools implementation of ToString. The compiler tries to recursively call the method ToString again instead of calling the ToString in namespace X.
I can't use X::ToString as that will fail when I try to instantiate the Tools class with a type from namespace Y. Eg, if I use:
namespace Y
{
class SomeOtherType
{
};
std::wstring ToString(SomeOtherType)
{
// ...
}
}
Y::SomeOtherType someOtherType;
auto s = Tools<Y::SomeOtherType>::ToString(someOtherType); // Would fail as SomeOtherType isn't in namespace X.
Is it possible to make this work?
I'm using VS 2015 Update 3. A solutions that work for that is preferred.
Related: calling a global function with a class method with the same declaration
Ok, I might have a solution. Add an intermediate function that is outside the class with a different name, that then calls with the correct name.
Add
namespace ImplementationDetail
{
template< class T >
auto ToStringHelper(T& t)
{
return ToString(t);
}
}
template<class T>
class Tools
{
auto ToString(T& t)
{
return ImplementationDetail::ToStringHelper(t);
}
}
Explicitly use
return ::X::ToString(t);
to reference the function in the X namespace, irrespective of which namespace the reference comes from.
Related
I have a need to implement 2 functions inside a templated class, where both functions do similar things, but not everything is the same. My proposed solution was to use if constexpr on a single template function, and then have an alias for each function:
template <typename T>
class MyClass
{
private:
template <bool test>
void TestFunc()
{
if constexpr(test)
{
// Do something
}
else
{
// Do other stuff
}
}
public:
?????? TestTrue = TestFunc<true>;
?????? TestFalse = TestFunc<false>;
}
I'm trying to figure out what should go where the question marks are, so far using, auto and const auto have not worked. I want the user to be able to call TestTrue() and TestFalse() directly from an object of the class directly.
You could do:
void TestTrue() { TestFunc<true>(); }
void TestFalse() { TestFunc<false>(); }
I don't think there's a better way.
For completeness, here's the ugly way.
As mentioned in the comments, TestFunc is a member function, not a type, so if you want to reference an explicit specialization of it, you'll need to use a member function pointer. In our case, these will be pointers of the following type.
using MemberTestFunction = void (MyClass::*)();
We can then acquire pointers to the true and false specialization of TestFunc like so:
template <typename T>
class MyClass
{
// ...
constexpr static MemberTestFunction TestTrue = &MyClass::TestFunc<true>;
constexpr static MemberTestFunction TestFalse = &MyClass::TestFunc<false>;
};
If you're not familiar with pointers to member functions, the syntax for calling TestTrue and TestFalse may look rather bizarre. If you're inside a member function, you can invoke these functions either by using the ->* operator, or by using std::invoke (C++17) from <functional>:
template <typename T>
class MyClass
{
// ...
void foo() {
// Direct call with pointer.
(this->*TestTrue)();
// Call using std::invoke.
std::invoke(TestTrue, this);
}
};
Alternatively, outside of MyClass, these calls would look like the following.
MyClass<nullptr_t> x;
// Using type deducation.
(x.*decltype(x)::TestTrue)();
// Using fully qualified name.
(x.*MyClass<nullptr_t>::TestTrue)();
// Using std::invoke (with type deducation).
std::invoke(decltype(x)::TestTrue, x);
It goes without saying this this is a needlessly obscure way of accomplishing any otherwise simple task. I would not advocate using this technique over creating new functions (as HolyBlackCat suggested) or simply naming TestFunc<true>() and TestFunc<false>() explicitly at the call site.
Transform function TestFunc to functor:
#include <iostream>
template <typename T>
class MyClass
{
private:
template <bool test>
struct TestFunc
{
void operator()() {
if constexpr(test)
{
std::cout << "TestTrue\n";
}
else
{
std::cout << "TestFalse\n";
}
}
};
public:
TestFunc<true> TestTrue;
TestFunc<false> TestFalse;
};
int main()
{
MyClass<int> myClass;
myClass.TestTrue();
myClass.TestFalse();
}
I would like to place a std::variant inside a class and return its elements with a template function. Here is an example:
#include <string>
#include <variant>
class Class {
public:
std::variant<std::string, double> cont;
Class() {}
template <class V> Class(const V v) { cont = v; }
template <typename V> V fun() {
if (std::holds_alternative<double>(cont))
return std::get<double>(cont);
else if (std::holds_alternative<std::string>(cont))
return std::get<std::string>(cont);
}
};
int main() {
Class c;
c = 20;
double d = c.fun<double>();
return 0;
}
I try to return the elements of the class Class through the template function fun. However, gcc-9.1 refuses to compile the code and tells me
Class.cpp:12:46: error: cannot convert ‘std::__cxx11::basic_string<char>’ to ‘double’ in return
12 | return std::get<std::string>(cont);
Why is there any attempt to convert the string (the second return type of the function foo) to a double? Can I prevent this and solve the problem? Do I use the std::variant class unidiomatic?
The issue here is that you query the current value stored at runtime, while the function signature of the template instantiation is performed at compile time. Consider how the member function looks like when you try using it to retrieve a double:
double fun() {
if (/* ... */)
return std::get<double>(cont); // Ok return type is double, too
else if (/* ... */)
return std::get<std::string>(cont); // Error, return type should be string?!
}
This can't work. You need to change the way to access the data member, e.g. passing an overload set to std::visit, by providing two getter-like functions returning std::optional<double> and std::optional<std::string> or something similar.
All runtime if branches must be compilable even if not taken. If we call fun() with V == double then returning an std::string makes no sense and causes the error (even if that branch would never be taken, the compiler can't know that for certain).
Instead, just return it right away through V:
template <typename V> V fun() {
if (std::holds_alternative<V>(cont))
return std::get<V>(cont);
return {}; // return default constructed V. You could throw an exception here instead etc.
}
Has anyone ever used pointers/references/pointer-to-member (non-type) template parameters?
I'm not aware of any (sane/real-world) scenario in which that C++ feature should be used as a best-practice.
Demonstation of the feature (for pointers):
template <int* Pointer> struct SomeStruct {};
int someGlobal = 5;
SomeStruct<&someGlobal> someStruct; // legal c++ code, what's the use?
Any enlightenment will be much appreciated!
Pointer-to-function:
Pointer-to-member-function and pointer-to-function non-type parameters are really useful for some delegates. It allows you to make really fast delegates.
Ex:
#include <iostream>
struct CallIntDelegate
{
virtual void operator()(int i) const = 0;
};
template<typename O, void (O::*func)(int)>
struct IntCaller : public CallIntDelegate
{
IntCaller(O* obj) : object(obj) {}
void operator()(int i) const
{
// This line can easily optimized by the compiler
// in object->func(i) (= normal function call, not pointer-to-member call)
// Pointer-to-member calls are slower than regular function calls
(object->*func)(i);
}
private:
O* object;
};
void set(const CallIntDelegate& setValue)
{
setValue(42);
}
class test
{
public:
void printAnswer(int i)
{
std::cout << "The answer is " << 2 * i << "\n";
}
};
int main()
{
test obj;
set(IntCaller<test,&test::printAnswer>(&obj));
}
Live example here.
Pointer-to-data:
You can use such non-type parameters to extend the visibility of a variable.
For example, if you were coding a reflexion library (which might very useful for scripting), using a macro to let the user declare his classes for the library, you might want to store all data in a complex structure (which may change over time), and want some handle to use it.
Example:
#include <iostream>
#include <memory>
struct complex_struct
{
void (*doSmth)();
};
struct complex_struct_handle
{
// functions
virtual void doSmth() = 0;
};
template<complex_struct* S>
struct csh_imp : public complex_struct_handle
{
// implement function using S
void doSmth()
{
// Optimization: simple pointer-to-member call,
// instead of:
// retrieve pointer-to-member, then call it.
// And I think it can even be more optimized by the compiler.
S->doSmth();
}
};
class test
{
public:
/* This function is generated by some macros
The static variable is not made at class scope
because the initialization of static class variables
have to be done at namespace scope.
IE:
class blah
{
SOME_MACRO(params)
};
instead of:
class blah
{
SOME_MACRO1(params)
};
SOME_MACRO2(blah,other_params);
The pointer-to-data template parameter allows the variable
to be used outside of the function.
*/
std::auto_ptr<complex_struct_handle> getHandle() const
{
static complex_struct myStruct = { &test::print };
return std::auto_ptr<complex_struct_handle>(new csh_imp<&myStruct>());
}
static void print()
{
std::cout << "print 42!\n";
}
};
int main()
{
test obj;
obj.getHandle()->doSmth();
}
Sorry for the auto_ptr, shared_ptr is available neither on Codepad nor Ideone.
Live example.
The case for a pointer to member is substantially different from pointers to data or references.
Pointer to members as template parameters can be useful if you want to specify a member function to call (or a data member to access) but you don't want to put the objects in a specific hierarchy (otherwise a virtual method is normally enough).
For example:
#include <stdio.h>
struct Button
{
virtual ~Button() {}
virtual void click() = 0;
};
template<class Receiver, void (Receiver::*action)()>
struct GuiButton : Button
{
Receiver *receiver;
GuiButton(Receiver *receiver) : receiver(receiver) { }
void click() { (receiver->*action)(); }
};
// Note that Foo knows nothing about the gui library
struct Foo
{
void Action1() { puts("Action 1\n"); }
};
int main()
{
Foo foo;
Button *btn = new GuiButton<Foo, &Foo::Action1>(&foo);
btn->click();
return 0;
}
Pointers or references to global objects can be useful if you don't want to pay an extra runtime price for the access because the template instantiation will access the specified object using a constant (load-time resolved) address and not an indirect access like it would happen using a regular pointer or reference.
The price to pay is however a new template instantiation for each object and indeed it's hard to think to a real world case in which this could be useful.
The Performance TR has a few example where non-type templates are used to abstract how the hardware is accessed (the hardware stuff starts at page 90; uses of pointers as template arguments are, e.g., on page 113). For example, memory mapped I/O registered would use a fixed pointer to the hardware area. Although I haven't ever used it myself (I only showed Jan Kristofferson how to do it) I'm pretty sure that it is used for development of some embedded devices.
It is common to use pointer template arguments to leverage SFINAE. This is especially useful if you have two similar overloads which you couldn't use std::enable_if default arguments for, as they would cause a redefinition error.
This code would cause a redefinition error:
template <typename T, typename = std::enable_if_t<std::is_integral<T>::value>>
void foo (T x)
{
cout << "integral";
}
template <typename T, typename = std::enable_if_t<std::is_floating_point<T>::value>>
void foo (T x)
{
cout << "floating";
}
But this code, which utilises the fact that valid std::enable_if_t constructs collapse to void by default, is fine:
// This will become void* = nullptr
template <typename T, std::enable_if_t<std::is_integral<T>::value>* = nullptr>
void foo (T x)
{
cout << "integral";
}
template <typename T, std::enable_if_t<std::is_floating_point<T>::value>* = nullptr>
void foo (T x)
{
cout << "floating";
}
Occasionally you need to supply a callback function having a particular signature as a function pointer (e.g. void (*)(int)), but the function you want to supply takes different (though compatible) parameters (e.g. double my_callback(double x)), so you can't pass its address directly. In addition, you might want to do some work before and after calling the function.
It's easy enough to write a class template that tucks away the function pointer and then calls it from inside its operator()() or some other member function, but this doesn't provide a way to extract a regular function pointer, since the entity being called still requires the this pointer to find the callback function.
You can solve this problem in an elegant and typesafe way by building an adaptor that, given an input function, produces a customised static member function (which, like a regular function and unlike a non-static member function, can have its address taken and used for a function pointer). A function-pointer template parameter is needed to embed knowledge of the callback function into the static member function. The technique is demonstrated here.
There is some class which have methods like:
int getSomething1();
std::string getSomething2();
someClass getSomething3();
There is structure which describes fields of this class like:
{"name of field", pointer to getter, std::type_info}
Then I would like to use it as follows:
if(type == int){
field_int = (int)getter();
}
else if(type == std::string){
field_string = (std::string)getter();
}
etc.
How to transform getters like
int getSomething1();
std::string getSomething2();
etc.
to some universal function pointer and then to get the correct value of field?
This answer of mine to another question addresses your problem pretty well. With some minor modifications, you get this:
template<class C, class T>
T get_attribute(const C& instance, T (C::*func)() const) {
return (instance.*func)();
}
Assuming the following:
struct Foo {
int getSomething1() const;
std::string getSomething2() const;
someClass getSomething3() const;
};
You can use it like this:
Foo foo;
int value = get_attribute<Foo, int>(foo, &Foo::getSomething1);
std::string value = get_attribute<Foo, std::string>(foo, &Foo::getSomething2);
someClass value = get_attribute<Foo, someClass>(foo, &Foo::getSomething3);
You can of course transform get_attribute to a functor to bind some or all of the arguments.
There is no formal universal function pointer, the equivalent of void*
for data. The usual solution is to use void (*)(); you are guaranteed
that you can convert any (non-member) function pointer to this (or any
other function pointer type) and back without loss of information.
If there is a certain similarity in the function signatures (e.g. all
are getters, with no arguments) and how they are used, it may be
possible to handle this with an abstract base class and a set of derived
classes (possibly templated); putting pointers to instances of these
classes in a map would definitely be more elegant than an enormous
switch.
What you are trying to achieve can be better achieved with already existing containers such as a boost fusion sequence. I'd advice that you try this first.
Templates to the rescue!
// Create mapping of type to specific function
template <typename T> T getSomething(); // No default implementation
template <> int getSomething<int>() { return getSomething1(); }
template <> std::string getSomething<std::string>() { return getSomething2(); }
template <> someClass getSomething<someClass>() { return getSomething3(); }
// Convenience wrapper
template <typename T> void getSomething(T& t) { t = getSomething<T>(); }
// Use
int i = getSomething<int>();
std::string s;
getSomething(s);
As I understand, your difficulty is in storing the function pointers, since they are of different types. You can solve this using Boost.Any and Boost.Function.
#include <boost/any.hpp>
#include <boost/function.hpp>
int getInt() {
return 0;
}
std::string getString() {
return "hello";
}
int main()
{
boost::function<boost::any ()> intFunc(getInt);
boost::function<boost::any ()> strFunc(getString);
int i = boost::any_cast<int>(intFunc());
std::string str = boost::any_cast<std::string>(strFunc());
}
I need to instantiate a free template function (FTF) within a template class (TC). The FTF takes as a template parameter one of the template parameters of the TC. The TC also holds generic pointers to these FTF's, and these functions are called through the pointers.
The step of taking a pointer to a FTF is not enough to instantiate it, and I receive linker errors from the GCC toolchain. MSDN illustrates FTF specification as so -- however my instantion of the FTF is dependant on a template parameter of my TC, and therefore the FTF instantiation cannot be placed in free scope.
Is this possible ? I am attaching some basic generated code, the issue is in the constructor of the class test_service, where I assign the pointer of a free function into a custom container. I get a linker error telling me the free function cannot be found (uninstantiated). I know that specifying a call to the template function in the class somewhere will produce a instantiation, however I am only going to be making a call via a pointer.
#include "rpc_common.h"
#include <boost/cstdint.hpp>
namespace rubble { namespace rpc {
struct test_service_dummy_tag{};
template<typename T>
class test_service_skel
{
public:
bool Init() {}
bool TearDown() {}
bool test_one(TestRequest,TestResponse){};
private:
};
template<typename T_IMPL>
bool test_service_test_one(T_IMPL & impl,ClientRequest & request)
{
return 0;
}
template<typename T_IMPL=test_service_skel<test_service_dummy_tag> >
class test_service
{
public:
test_service()
{
// uncomment the following two lines and a instantiation will occur.
// ClientRequest cr;
//test_service_test_one<T_IMPL>(m_impl,cr);
m_dispatch_table.SetEntry( Oid("test_one",0),(void *) & test_service_test_one<T_IMPL>);
}
bool Init() { return m_impl.Init(); };
bool TearDown() { return m_impl.TearDown(); };
private:
T_IMPL m_impl;
OidContainer<Oid,void *> m_dispatch_table;
};
} }
EDIT: self-contained minimal version
class test_skel
{
bool test_function()
{
return true;
}
};
template<typename T>
bool test_function()
{
}
template<typename T = test_skel>
class test
{
public:
test()
{
dispatch = (void *) & test_function<T>;
}
void * dispatch;
};
int main()
{
test<> t;
return 0;
}
There is no problem iff you don't use a void*, i.e.: http://www.ideone.com/eRgUG
However, if you insist on storing the pointer in a void*, then you need to take the address using a specific function pointer first and then cast - e.g.
bool (*temp)() = &test_function<T>;
dispatch = reinterpret_cast<void*>(temp); // YUCK
This gives the compiler enough context to generate the address for you.
Ahh - just saw DeadMG's answer, the function to generate the void* is neater...
Your self-contained example wouldn't compile for me with a strange error about overloaded functions, when there is no overloading going on, with MSVC. I did, however, manage to work around it.
class test_skel
{
bool test_function()
{
return true;
}
};
template<typename T> void* to_void_pointer(T t) {
return reinterpret_cast<void*>(t);
}
template<typename T>
bool test_function()
{
return true;
}
template<typename T = test_skel>
class test
{
public:
test()
{
dispatch = to_void_pointer(&test_function<T>);
}
void * dispatch;
};
int main()
{
test<> t;
return 0;
}
This compiles cleanly. I suspect that whatever behaviour you're seeing and I saw is a compiler error.