C++ template struct 'has no member named' error - c++

The only way I can get this to compile without issuing a warning on no member a when T==B and so on for T==A is to reinterpret_cast within the if statement blocks and access the non-shared members via a pointer. Is there no way to get around this or hint to the compiler otherwise?
This is gcc 4.8.x
enum Type { A, B};
template<Type T> struct S { };
template<> struct S<A> { int x; int a; };
template<> struct S<B> { int y; int x; int b; };
template<Type T> static void foo(int x)
{
// lots of code
S<T> s;
s.x = someCall();
if (T == A)
{
s.a = 1;
}
else if (T == B)
{
s.y = 2;
s.b = 3;
}
// a bunch of common code
}
Edit: I know about making a dedicated specific functions to handle the specifics but I was hoping to avoid extra boilerplate code.

You may use specialization:
template <Type T> void bar(S<T>&);
template <> void bar(S<A>& s) {s.a = 1;}
template <> void bar(S<B>& s) {s.y = 2; s.b = 3;}
template<Type T> static void foo(int x)
{
// lots of code
S<T> s;
s.x = someCall();
bar(s);
// a bunch of common code
}

if (T == A)
[...]
else if (T == B)
[...]
A, B and T here are compile-time entities, not run-time entities. And yet you are attempting to perform a run-time evaluation of something that is known at compile time. Now sure, you could try to hack up something with a kind of iffy cast (try, and fail), or try some other kind of kludgery, but the code is telling you: you're doing it wrong.
Specializing foo is one way, as may be levarging SFINAE (as with enable_if), but from what little I can see here of your use case, that would be doing it wrong too. That's because the code you look to be implementing is some kind of initialization code, or code that manipulates the internal state of the object being used. In a sense, you're violating the principle of single responsibility.
So move that code to where the responsibility belongs: in the class that's being inited.
template<> struct S<A> { int x; int a; void init() {a=1;} };
template<> struct S<B> { int y; int x; int b; void init() { x=2; y=3; } };
template<Type T> static void foo(int x)
{
// lots of code
S<T> s;
s.x = someCall();
s.init();
// a bunch of common code
}
You could also use a factory class. This would abstract away both the instantiation of the object, and the call to init(), which can take different parameters depending on the ultimate type.

Related

How to correctly forward/wrap static_cast?

Basicly, I need a static_cast function wrapper to use as a predicate (for conversion), since static_cast directly is not usable in this way. Lambda is not preferred this time. My implemention:
template<typename T>
struct static_cast_forward{
template<class U>
T operator()(U&& u) const {
return static_cast<T>(std::forward<U>(u));
}
};
First, while I do have a fundamental understanding of rvalue references, etc. I want to verify if this is the correct way to implement this forward/wrapper ?
Second, to ask if any std or boost library already provide this functionality ?
Extra: would you forward other casts in the same way ?
ACTUAL CASE:
My actual case is to use with boost::range, something like:
//auto targetsRange = mixedRange | boost::adaptors::filtered(TYPECHECK_PRED) | boost::adaptors::transformed(static_cast_forward<TARGET_PTR_TYPE>());
WORKING EXAMPLES:
#include <algorithm>
template<typename T>
struct static_cast_forward {
template<class U>
T operator()(U&& u) const {
return static_cast<T>(std::forward<U>(u));
}
};
//example 1:
void test1() {
std::vector<double> doubleVec{1.1, 1.2};
std::vector<int> intVec;
std::copy(doubleVec.begin(), doubleVec.end(), intVec.end());//not ok (compiles, but gives warning)
std::transform(doubleVec.begin(), doubleVec.end(), std::back_inserter(intVec), static_cast_forward<int>()); //ok
}
//example 2:
struct A {
virtual ~A() {}
};
struct B : public A {
};
struct C : public A {
};
void test2() {
std::vector<A*> vecOfA{ new B, new B};
std::vector<B*> vecOfB;
//std::transform(vecOfA.begin(), vecOfA.end(), std::back_inserter(vecOfB), static_cast<B*>); //not ok: syntax error..
std::transform(vecOfA.begin(), vecOfA.end(), std::back_inserter(vecOfB), static_cast_forward<B*>() ); //ok
}
Addition after the question has been clarified.
In both cases you don't need to std::forward anything, because there is nothing to move, you need just a cast. But if you want to generalize to movable types, too, then your implementation seems fine to me. Just don't call it forward because it is not a forward. As far as I know, there is nothing in std to mimic your struct.
So I would just add test3() that really needs moving:
struct B { };
struct D {
explicit D(B&&) { } // Note: explicit!
};
void test3()
{
std::vector<B> vb{B{}, B{}};
std::vector<D> vd;
// Won't compile because constructor is explicit
//std::copy(std::make_move_iterator(vb.begin()), std::make_move_iterator(vb.end()), std::back_inserter(vd));
// Works fine
std::transform(std::make_move_iterator(vb.begin()), std::make_move_iterator(vb.end()), std::back_inserter(vd), static_cast_forward<D>());
}
Answer before question was clarified.
If I correctly understood your intention, then this is what you want:
template<typename T>
struct static_cast_forward {
template<class U>
decltype(auto) operator()(U&& u) const
{
if constexpr (std::is_lvalue_reference_v<U>)
return static_cast<T&>(u);
else
return static_cast<T&&>(u);
}
};
Then you have:
struct B { };
struct D : B { };
void foo() {
D d;
static_cast_forward<B> scf_as_B;
static_assert(std::is_same_v<decltype(scf_as_B(D{})), B&&>);
static_assert(std::is_same_v<decltype(scf_as_B(d)), B&>);
}

Why would I want a .* operator in C++?

I recently found out that the .* operator (and the closely related ->* operator) exists in C++. (See this question.)
Seems neat at first, but why would I ever need such a thing? The two answers in the linked question provided contrived examples which would benefit from a direct function call.
Where a direct function call is inconvenient, a function object could be used instead, like the lambda functions that may be used in std::sort. This removes a level of indirection and hence would be more performant than using .*.
The linked question also mentioned a simplified version of this example:
struct A {
int a;
int b;
};
void set_member(A& obj, int A::* ptr, int val){
obj.*ptr = val;
}
int main()
{
A obj;
set_member(obj, &A::b, 5);
set_member(obj, &A::a, 7);
// Both members of obj are now assigned
}
But it's pretty trivial (perhaps even better practice because it's cleaner and isn't unnecessarily constrained to members of A) to do this instead:
struct A {
int a;
int b;
};
void set_me(int& out, int val){
out = val;
}
int main()
{
A obj;
set_me(obj.b, 5);
set_me(obj.a, 7);
// Both members of obj are now assigned
}
In conclusion, a pointer-to-member-function might be replaced by a function object, and a pointer-to-member-variable might be replaced by a direct reference of said variable or a function object. Doing so might also increase the efficiency of the code due to one less indirection.
This question only provides examples where my conclusion stands, so it does not answer my question.
Apart from interfacing legacy code which uses .* (in which there would be no choice at all), when, really, would I want to use .*?
Your example is too trivial to be illustrative. Consider a bit more complicated one
struct A {
int a;
int b;
};
void set_n_members(A objs[], unsigned n, int A::* ptr, int val)
{
for (unsigned i = 0; i < n; ++i)
objs[i].*ptr = val;
}
int main()
{
A objs[100];
set_n_members(objs, 100, &A::b, 5);
set_n_members(objs, 100, &A::a, 7);
}
How would you rewrite this without int A::* ptr and without inducing code bloat?
You could create collections of pointers to members and iterate over them. E.g.:
struct UserStrings
{
std::string first_name;
std::string surname;
std::string preferred_name;
std::string address;
};
...
std::array<std::string UserStrings::*, 4> str_cols = { &UserStrings::first_name, &UserStrings::surname, &UserStrings::preferred_name, &UserStrings::address };
std::vector<UserStrings> users = GetUserStrings();
for (auto& user : users)
{
for (auto& column : str_cols)
{
SanitizeForSQLQuery(user.*column);
}
}
It is used to implement std::mem_fn, which is used to implement std::function.
The following code shows how the ->* operator works in a naive Function class implemention.
Similarly, you can implement a member invoker class using the .* operator and a class reference.
#include <iostream>
class A
{
public:
void greet()
{
std::cout << "Hello world"<<std::endl;
}
};
template<typename R, typename ...TArgs>
class Invoker
{
public:
virtual R apply(TArgs&& ...args) = 0;
};
template<typename C, typename R, typename ...TArgs>
class MemberInvoker :public Invoker<R, TArgs...>
{
protected:
C* sender;
R(C::*function)(TArgs ...args);
public:
MemberInvoker(C* _sender, R(C::*_function)(TArgs ...args))
:sender(_sender)
, function(_function)
{
}
virtual R apply(TArgs&& ...args) override
{
return (sender->*function)(std::forward<TArgs>(args)...);
}
};
template<typename T>
class Func
{
};
template<typename R, typename ...TArgs>
class Func<R(TArgs...)>
{
public:
Invoker<R,TArgs...>* invoker=nullptr;
template<typename C>
Func(C* sender, R(C::*function)(TArgs...))
{
invoker =new MemberInvoker<C, R, TArgs...>(sender, function);
}
R operator()(TArgs&& ...args)
{
return invoker->apply(std::forward<TArgs>(args)...);
}
~Func()
{
if (invoker)
{
delete invoker;
invoker = nullptr;
}
}
};
int main()
{
A a;
Func<void()> greetFunc(&a, &A::greet);
greetFunc();
system("PAUSE");
}
Let's say you wanted to write a LINQ style library for C++ that could be used something like this:
struct Person
{
std::string first_name;
std::string last_name;
std::string occupation;
int age;
int children;
};
std::vector<Person> people = loadPeople();
std::vector<std::string> result = from(people)
.where(&Person::last_name == "Smith")
.where(&Person::age > 30)
.select("%s %s",&Person::first_name,&Person::last_name);
for(std::string person : result) { ... };
Under the covers, the where function accepts an expression tree containing a pointer to member (among other stuff) and is applied to each vector item looking for one that matches. The select statement accepts a format string and some pointer to members and does an sprintf style formatting of whichever vector items get through the where statements.
I have written something like this, and there are several others out there that do it slightly differently (Is there a LINQ library for C++?). Pointer-to-member allows the library user to specify whichever members of their struct that they want and the library doesn't need to know anything about what they might do.

C++ Runtime variable in templates

template <int ns, int id>
class Bar
{
public:
static int value;
};
template <int ns, int id>
int Bar<ns, id>::value = 0;
class Foo
{
public:
template <int ns, int id>
static int GetNextValue()
{
++Bar<ns, id>::value;
return Bar<ns, id>::value;
}
};
class Baz
{
public:
Baz(int value)
: value(value)
{
}
void PrintBaz();
private:
int value;
};
This works fine when called like:
Baz baz(Foo::GetNextValue<1, 1>());
I need this code to support the following.
int ns = 1;
int id = 5;
Baz baz(Foo::GetNextValue<ns, id>());
Compilation for this code fails understandably. Is there a way to have template meta-programming support runtime variable values?
Pointer to solution for this problem by any other method will also be helpful.
The simple answer is no, templates are a compile time construct. You might want to consider constexpr functions if you need code that can be evaluated at compile time or runtime.
A template meta programm "runs" during compilation. So every input into it must be known at compile time.
Think of this:
template<int N>
int get(void) {
return N;
}
This creates a completely new function on each instantiation with a different value for N. So if the passed value of some instantiation isn't known at compile time, this would mean that the new function had to be generated during runtime. For this to work you'd need the compiler to be part of your final application. It might seem simple in this case, but there are pretty complex meta programms out there.
Moreover, even the syntax of C++ depends on the results of some meta programms:
template<bool = true>
struct switch {
template<int>
using thing = int;
};
template<>
struct switch<false> {
int thing = 21;
}
switch<META>::thing<42>(21);
// bool result of comparisons: 21 < 42 > 21
// or int result from cast: 21

C++ auto deduction of return type

I want to write a function that return different types based on different input as below.
enum MyType
{
A,
B
};
template<MyType T> struct MyStruct
{
};
static auto createMyStruct(MyType t)
{
if(t==A)
return MyStruct<A>();
else
return MyStruct<B>();
}
It didn't work out because there are two return types for one auto. Is there any other way to do this?
There is absolutely no way of having a (single) function that returns different types based on a runtime decision. The return type has to be known at compile time. However, you can use a template function, like this (thanks to #dyp for making me simplify the code):
#include <iostream>
#include <typeinfo>
enum MyType
{
A,
B
};
template<MyType>
struct MyStruct {};
template<MyType type>
MyStruct<type> createMyStruct()
{
return {};
}
int main()
{
auto structA = createMyStruct<A>();
auto structB = createMyStruct<B>();
std::cout << typeid(structA).name() << std::endl;
std::cout << typeid(structB).name() << std::endl;
}
I am assuming you want to write code like this:
void foo (MyType t) {
auto x = createMyStruct(t);
//... do something with x
}
You are attempting to derive the right type for x at runtime. However, the return type of a function must be known at compile time, and the type resolution for auto is also determined at compile time.
You could instead restructure your code to be like this:
template<MyType T> struct MyStruct
{
//...
static void foo () {
MyStruct x;
//... do something with x
}
};
The idea is to write a single foo() function whose only difference is the type of thing it is manipulating. This function is encapsulated within the type itself. You can now make a runtime decision if you have a mapping between MyType and MyStruct<MyType>::foo.
typedef std::map<MyType, void(*)()> MyMap;
template <MyType...> struct PopulateMyMap;
template <MyType T> struct PopulateMyMap<T> {
void operator () (MyMap &m) {
m[T] = MyStruct<T>::foo;
}
};
template <MyType T, MyType... Rest> struct PopulateMyMap<T, Rest...> {
void operator () (MyMap &m) {
m[T] = MyStruct<T>::foo;
PopulateMyMap<Rest...>()(m);
}
};
template<MyType... Types> void populateMyMap (MyMap &m) {
PopulateMyMap<Types...>()(m);
}
//...
populateMyMap<A, B>(myMapInstance);
Then, to make a runtime decision:
void foo (MyType t) {
myMapInstance.at(t)();
}
I think you should learn abstract factory design pattern.
For use objects of type MyStruct<A> or MyStruct<B> you need common interface.
Common interface provided in abstract base class.
struct MyStruct
{
virtual ~MyStruct() {}
virtual void StructMethod() = 0;
};
struct MyStructA: public MyStruct
{
void StructMethod() override {}
};
struct MyStructB: public MyStruct
{
void StructMethod() override {}
};
std::unique_ptr<MyStruct> createMyStruct(MyType t)
{
if (t==A)
return std::make_unique<MyStructA>();
else
return std::make_unique<MyStructB>();
}

C++ specialization, type_of or just typeid

I would like to know what is better to use in my situation and why. First of all I heard that using RTTI (typeid) is bad. Anyone could explain why? If I know exactly types what is wrong to compare them in a runtime? Furthermore is there any example how to use boost::type_of? I have found none searching through the mighty google :) Other solution for me is specialization, but I would neet to specialize at least 9 types of new method. Here is an example what I need:
I have this class
template<typename A, typename B, typename C>
class CFoo
{
void foo()
{
// Some chunk of code depends on old A type
}
}
So I need to rather check in typeid(what is I heard is BAD) and make these 3 realizations in example like:
void foo()
{
if (typeid(A) == typeid(CSomeClass)
// Do this chunk of code related to A type
else
if (typeid(B) == typeid(CSomeClass)
// Do this chunk of code related to B type
else
if (typeid(C) == typeid(CSomeClass)
// Do this chunk of code related to C type
}
So what is the best solution? I don't want to specialize for all A,B,C, because every type is has 3 specializations so I will get 9 methods or just this typeid check.
It's bad because
A, B and C are known at compile-time but you're using a runtime mechanism. If you invoke typeid the compiler will make sure to include metadata into the object files.
If you replace "Do this chunk of code related to A type" with actual code that makes use of CSomeClass's interface you'll see you won't be able to compile the code in case A!=CSomeClass and A having an incompatible interface. The compiler still tries to translate the code even though it is never run. (see example below)
What you normally do is factoring out the code into separate function templates or static member functions of classes that can be specialized.
Bad:
template<typename T>
void foo(T x) {
if (typeid(T)==typeid(int*)) {
*x = 23; // instantiation error: an int can't be dereferenced
} else {
cout << "haha\n";
}
}
int main() {
foo(42); // T=int --> instantiation error
}
Better:
template<typename T>
void foo(T x) {
cout << "haha\n";
}
void foo(int* x) {
*x = 23;
}
int main() {
foo(42); // fine, invokes foo<int>(int)
}
Cheers, s
Well generally solutions can be come up with without RTTI. It "can" show you haven't thought the design of the software out properly. THAT is bad. Sometimes RTTI can be a good thing though.
None-the-less there IS something odd in what you want to do. Could you not create an interim template designed something like as follows:
template< class T > class TypeWrapper
{
T t;
public:
void DoSomething()
{
}
};
then partially specialise for the functions you want to as follows:
template<> class TypeWrapper< CSomeClass >
{
CSomeClass c;
public:
void DoSomething()
{
c.DoThatThing();
}
};
Then in your class define above you would do something such as ...
template
class CFoo
{
TypeWrapper< A > a;
TypeWrapper< B > b;
TypeWrapper< C > c;
void foo()
{
a.DoSomething();
b.DoSomething();
c.DoSomething();
}
}
This way it only actually does something in the "DoSomething" call if it is going through the partially specialised template.
The problem lies in the code chunks you write for every specialization.
It doesn't matter if you write (lengthwise)
void foo()
{
if (typeid(A) == typeid(CSomeClass)
// Do this chunk of code related to A type
else
if (typeid(B) == typeid(CSomeClass)
// Do this chunk of code related to B type
else
if (typeid(C) == typeid(CSomeClass)
// Do this chunk of code related to C type
}
or
void foo()
{
A x;
foo_( x );
B y;
foo_( y );
C z;
foo_( z );
}
void foo_( CSomeClass1& ) {}
void foo_( CSomeClass2& ) {}
void foo_( CSomeClass3& ) {}
The upside of the second case is, when you add a class D, you get reminded by the compiler that there is an overload for foo_ missing which you have to write. This can be forgotten in the first variant.
I'm afraid this is not going to work in the first place. Those "chunks of code" have to be compilable even if the type is not CSomeClass.
I don't think type_of is going to help either (if it is the same as auto and decltype in C++0x).
I think you could extract those three chunks into separate functions and overload each for CSomeClass. (Edit: oh there are else if's. Then you might indeed need lots of overloads/specialization. What is this code for?)
Edit2: It appears that your code is hoping to do the equivalent of the following, where int is the special type:
#include <iostream>
template <class T>
bool one() {return false; }
template <>
bool one<int>() { std::cout << "one\n"; return true; }
template <class T>
bool two() {return false; }
template <>
bool two<int>() { std::cout << "two\n"; return true; }
template <class T>
bool three() {return false; }
template <>
bool three<int>() { std::cout << "three\n"; return true; }
template <class A, class B, class C>
struct X
{
void foo()
{
one<A>() || two<B>() || three<C>();
}
};
int main()
{
X<int, double, int>().foo(); //one
X<double, int, int>().foo(); //two
X<double, double, double>().foo(); //...
X<double, double, int>().foo(); //three
}
I think you've got your abstractions wrong somewhere.
I would try redefining A, B & C in terms of interfaces they need to expose (abstract base classes in C++ with pure virtual methods).
Templating allows basically duck-typing, but it sounds like CFoo knows too much about the A B & C classes.
typeid is bad because:
typeid can be expensive, bloats
binaries, carries around extra
information that shouldn't be
required.
Not all compilers support it
It's basically breaking the class hierarchy.
What I would recommend is refactoring: remove the templating, instead define interfaces for A, B & C, and make CFoo take those interfaces. That will force you to refactor the behaviour so the A, B & C are actually cohesive types.