This question already has answers here:
Where and why do I have to put the "template" and "typename" keywords?
(8 answers)
Closed 5 years ago.
Let's suppose I have two classes (actually more, but only 2 in my MCVE) defining two static functions with exactly the same name:
class A
{
public:
static void doSomething() {};
static void doSomethingElse() {};
};
class B
{
public:
static void doSomething() {};
static void doSomethingElse() {};
};
I want to call one of those functions for all available classes. So I created a helper function:
template<class Helper> static void ApplyToAllTypes( Helper& helper )
{
helper.apply<A>();
helper.apply<B>();
}
Then I do this to call doSomething on all classes:
class doSomethingHelper
{
public:
template<class T> static void apply()
{
T::doSomething();
}
};
void doSomethingToAll()
{
doSomethingHelper helper;
ApplyToAllTypes<doSomethingHelper>( helper );
}
And this to call doSomethingElse on all classes:
class doSomethingElseHelper
{
public:
template<class T> static void apply()
{
T::doSomethingElse();
}
};
void doSomethingElseToAll()
{
doSomethingElseHelper helper;
ApplyToAllTypes<doSomethingElseHelper>( helper );
}
It works fine when compiled with MSVC, but when I try to compile this with g++, it complains:
In static member function 'static void ApplyToAllTypes()':
error: expected '(' before '>' token
helper.apply<A>();
Is that really invalid? Should the sytax be fixed in any way or do I need to find an alternative (then proposed alternative would be appreciated)?
You have to write
helper.template apply<A>();
Visual Studio accepts this (wrong) syntax, though.
Related
Playing with C++ 20 modules, I have the following snippet:
export {
template<class T>
class Suite {
private:
std::vector<ConcreteBuilder<T>> things {};
};
template <class T>
class ConcreteBuilder : Builder<T> {
private:
// A collection of things of function pointers or functors
std::vector<std::function<void()>> things;
public:
// Virtual destructor
virtual ~TestBuilder() override {};
// Add a new thing to the collection of things
template<typename Function>
void add(Function&& fn) {
tests.push_back(std::forward<Function>(fn));
}
// override the build() base method from Builder<T>
virtual T build() const override {
return this->things;
}
};
}
And I am getting this Clang error:
error: use of undeclared identifier 'ConcreteBuilder'
std::vector<ConcreteBuilder> things {};
Why I can't access to a type that are in the same module at the same level?
The compiler compiles the file from the top down, not all at once. It is hitting the definition of std::vector<ConcreteBuilder<T>> before it gets to the definition of class ConcreteBuilder.
So, you need to move your definition of Suite after the definition of ConcreteBuilder, so the compiler knows what it is when you use it in the vector definition.
This question already has answers here:
Is there any reason to use this->
(16 answers)
Closed 7 years ago.
I have a code working like:
class base {
....
protected:
typeA m_mem;
}
class mymodule: public base{
....
void function(){
m_mem.call();
}
}
This was working OK before. Suddenly, I see it brokes saying "m_mem was not declared...." It might be some other people changed the namespace or other parts.
And I found it was working by just adding "this" then it compiles fine
this->m_mem.call()
While I just would like to know what's the cases that I must use "this" ? I learned "this" can be used to point to distinguish between class member and argument names. While for my case, what can be the reason that I must use "this" for accessing a data member
This can occur for example when you use templates.
The compiler will issue an error that x is an undefined variable for these class definitions
template <class T>
struct A
{
int x;
};
template <class T>
struct B : A<T>
{
void set_x( int v ) { x = v; }
};
If you write
void set_x( int v ) { this->x = v; }
the code will compile.
This question already has answers here:
templates: parent class member variables not visible in inherited class
(3 answers)
Closed 8 years ago.
When I compile the following templated C++ code with GCC 4.8.3
template <typename dtype> class Base {
public:
dtype base;
dtype ceiling;
Base() { };
virtual ~Base() { };
};
template<typename dtype> class Building : public Base<dtype> {
public:
dtype wall;
Building(dtype concrete) {
Base<dtype>::base=concrete;
ceiling=concrete;
wall=concrete;
};
~Building() { };
};
int main (int argc, char* argv[]) {
Building<float>* building=new Building<float>(2.0);
std::cout << building->base << std::endl;
}
I get the error
error: ‘ceiling’ was not declared in this scope
ceiling=concrete;
So it appears that
Base<dtype>::base=concrete;
works, but
ceiling=concrete;
does not. Is there any way I can mogrify this templated code so that, in the derived class constructor I can just reference "ceiling" from the templated base class without having to clarify which class it is from?
Thanks in advance
You can use this->ceiling.
I have a base class template which has 2 parameters, T is the derived class, flag means I want to activate some feature, default as false:
template
<
typename T,
bool flag
>
class SomeBase
{
public:
static Info& GetInfo()
{
static Info& instance = CreateInfo<T>(T::ClassName());
static bool inited = false;
if (!inited)
{
Test<flag>(instance);
inited = true;
}
return instance;
}
private:
template<bool enable>
static void Test(Info& instance)
{
return;
}
template<>
static void Test<true>(Info& instance)
{
T::Add(fields);
}
};
and to use this base:
class /*dllexport*/ MyClass : public SomeBase<MyClass, false>
{
public:
// ...
};
The flag template parameter is set to false, so according to my specialization, it should compiles the upper empty function, and the compiler does it, which is fine.
But, if I add dllexport to MyClass, then the compiler is giving C2039, which says 'Add' is not a member of MyClass, which doesnt make sense, because I am using SomeBase as flag == false.
Why does adding dllexport makes compiler try to compile the wrong specialization?
////////////////////////////////////////
Edit 1:
////////////////////////////////////////
According to this link:
http://msdn.microsoft.com/en-us/library/twa2aw10%28v=vs.100%29.aspx
Is the statement when one or more of the base classes is a specialization of a class template talking about SomeBase<MyClass, false>?
If so, the compiler implicitly applies dllexport to the specializations of class templates means the compiler is adding dllexport to SomeBase<MyClass, false>.
And, since I've already fully specialized static void Test(Info& instance), the compiler should choose the correct version of Test(), which is Test<false>().
So how come it is choosing(or compiling) the wrong version (Test<true>())?
Thanks!
Without dllexport, you will get the same error when you invoke MyClass::GetInfo from main.
In this case, compiler is expanding and compiling only part code that is invoked.
But with dllexport, it expands and compiles everything.
You can validate with this
template <typename T>
class SomeBase
{
public:
void test()
{
dafsaf;
}
private:
};
class /*__declspec(dllexport)*/ MyClass : public SomeBase<MyClass>
{
public:
// ...
};
int main()
{
MyClass o;
//o.test();
return 1;
}
I found detect class 's member use global template function is not work:
void printinfo(std::true_type)
{
cout<<"true_type!";
}
void printinfo(std::false_type)
{
cout<<"false_type!";
}
class TestAA
{
public:
void foo();
};
class TestBB;
template<typename T,typename =decltype(&T::foo)>
std::true_type havefoo(T*){return{};}
std::false_type havefoo(...){return{};}
int main()
{
printinfo(havefoo((TestAA*)nullptr));
printinfo(havefoo((TestBB*)nullptr));
}
class TestBB
{
public:
void foo();
};
it fail detect TestBB's foo,is normal? or a complier bug? gcc 4.8.1
The compiler hasn't seen the definition of TestBB at the point of the call to printinfo, only the forward declaration. At that point it doesn't know about any members of TestBB.