I am a beginner of c++ meta programming.
Now I test a code which is on a text book.
The following code is a copy of the code but it give me an error message
at line(1). At line(1), it seems the code tries to call Layer2::function with template keyword because it is following another template. Unfortunately, my compiler give me an error message, "error: expected ‘;’ before ‘::’ token.". Can anyone find a problem of the code?
Thank you very much.
template<typename T>
class Layer0 {
public:
template<int L1>
class Layer1 {
public:
template<int L2>
class Layer2 {
public:
virtual void function(void);
};
};
};
template<typename T, int L1>
class LayerTest {
public:
void pointer (typename Layer0<T>::template Layer1<L1>::template Layer2<L1>* ptr) {
// At the following line(1), I got an error message, error: expected ‘;’ before ‘::’ token.
ptr->template Layer2<L1>::function(); // (1) inhibit call of virtual function
}
};
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.
I am not sure if what I am trying to do is possible, but I have a hard time with the compiler trying to mock a method which contains a templated reference parameter.
The interface (removed all irrelevant methods)
class iat_protocol
{
public:
virtual void get_available_operators(etl::vector<network_operator, 5>&) = 0;
};
My mock
class at_protocol_mock : public iat_protocol
{
public:
MOCK_METHOD((void), get_available_operators, (etl::vector<network_operator, 5>&), (override));
};
This results in
In file included from /home/bp/dev/unode/eclipse/thirdparty/googletest/googlemock/include/gmock/gmock-actions.h:145,
from /home/bp/dev/unode/eclipse/thirdparty/googletest/googlemock/include/gmock/gmock.h:57,
from ../tests/shared/hal/at/at_channel_tests.cpp:1: /home/bp/dev/unode/eclipse/unit_tests/tests/shared/hal/at/mocks/at_protocol_mock.hpp: In member function ‘testing::internal::MockSpec<void(etl::vector<iobox::hal::at::network_operator, 5>&)> iobox::hal::at_protocol_mock::gmock_get_available_operators(const testing::internal::WithoutMatchers&, testing::internal::Function<void(etl::vector<iobox::hal::at::network_operator, 5>&)>*) const’: /home/bp/dev/unode/eclipse/thirdparty/googletest/googlemock/include/gmock/gmock-function-mocker.h:343:74: error: invalid combination of multiple type-specifiers 343 | typename ::testing::internal::Function<__VA_ARGS__>::template Arg<_i>::type
| ^~~~ /home/bp/dev/unode/eclipse/thirdparty/googletest/googlemock/include/gmock/internal/gmock-pp.h:17:31: note: in definition of macro ‘GMOCK_PP_IDENTITY’
My c++ skills are not good enough to have a clue what the compiler tries to tell me.
Who can help me ?
Well, this is strange, but simple using fixes your problem.
#include "gmock/gmock.h"
struct network_operator {};
namespace etl {
template <typename T, unsigned N>
struct vector {};
} // namespace etl
using vector_5 = etl::vector<network_operator, 5>;
class iat_protocol {
public:
virtual void get_available_operators(vector_5&) = 0;
};
class at_protocol_mock : public iat_protocol {
public:
MOCK_METHOD(void, get_available_operators,
(vector_5&),(override));
};
From gMock cookbook Dealing with unprotected commas
The latest gmock library shows the very more descriptive:
error: static_assert failed due to requirement '::testing::tuple_size<std::tuple<etl::vector<network_operator, 5> &>>::value == 2' "This method does not take 2 arguments. Parenthesize all types with unproctected commas."
MOCK_METHOD(void, get_available_operators,
Parenthesize all types with unproctected commas.
The other solution without using
#include "gmock/gmock.h"
struct network_operator {};
namespace etl {
template <typename T, unsigned N>
struct vector {};
} // namespace etl
using vector_5 = etl::vector<network_operator, 5>;
class iat_protocol {
public:
virtual void get_available_operators(etl::vector<network_operator, 5>&) = 0;
};
class at_protocol_mock : public iat_protocol {
public:
MOCK_METHOD(void, get_available_operators,
((etl::vector<network_operator, 5>&)), (override));
// ^ ^
};
I have a templated class:
template <typename vtype>
class BNode
{
public:
BNode::BNode(std::vector<BPoly<vtype>>& thePolys) {if(thePolys.size()) Build(thePolys);}
BNode::BNode() {}
BPlane* mPlane=nullptr;
//And more stuff
};
When I compile, I get this error on the BPlane* mPlane=nullptr line:
error C2146: syntax error: missing ';' before identifier 'BPlane'
(Using Visual Studio 2019 compiler)
Why do I need a semicolon after my {}? If I put the semicolon there, it works. But I'm curious what the problem is because I'm worried there's some issue that will bite me later.
The following code compile without any error:
#include <vector>
class BPlane;
template <class T> class BPoly { int i; };
template <typename vtype>
class BNode
{
public:
BNode(std::vector<BPoly<vtype>> &thePolys) { if (thePolys.size()) Build(thePolys); }
BNode() {}
BPlane *mPlane = nullptr;
void Build(...) {}
//And more stuff
};
int main()
{
BNode<char> s;
}
Thus, it is impossible to guess what you have done wrong as after writing simple types for missing declaration and including vector the code compile without adding any ; after a constructor.
And I have made an instantiation in main to be sure that the class is used.
Given the following templated class:
template<typename Container>
Class A
{
public:
A() : {}
bool push(std::shared_ptr<Container> container)
{
ptr_vec.emplace_back(container)
}
void load(Container c)
{
push(std::make_shared((Container)std::move(c));
}
private:
std::vector<std::shared_ptr<Container>> ptr_vec;
};
and the following code in main.cpp:
A<std::string> my_A {};
my_A.load("Hello");
I get the following error:
error: no matching function for call to 'make_shared(std::__cxx11::basic_string<char>)'
Can anyone shed some light regarding the error, and how to fix it?
Your given code has a lot of typos.
However, if you fix those(here: https://godbolt.org/z/M81qnh), the error is coming from std::make_shared function, which is a templated function. It needs the first argument to be explicitly specified
push(std::make_shared<Container>(std::move(c)));
// ^^^^^^^^^^
I'm noticing something strange in my code when I use constexpr initializers and enum template argumets. For example, the following code will compile:
enum class TestEnum1 {
Val1,
Val2
};
template <TestEnum1 EnumVal> class TestClass1 {
public:
constexpr TestClass1() {
}
};
class TestClass2 {
public:
TestClass1<TestEnum1::Val1> TestObject = TestClass1<TestEnum1::Val1>();
};
int main() {
TestClass2 testObj;
}
while the following will not:
enum class TestEnum1 {
Val1,
Val2
};
template <typename T, TestEnum1 EnumVal> class TestClass1 {
public:
constexpr TestClass1() {
}
};
class TestClass2 {
public:
TestClass1<int, TestEnum1::Val1> TestObject = TestClass1<int, TestEnum1::Val1>();
};
int main() {
TestClass2 testObj;
}
note that I only added another template argument before the existing one. The error message is something like:
error: 'enum class TestEnum1' is not a class or a namespace
error: expected ';' at end of member declaration
error: expected unqualified-id before '>' token
error: expected unqualified-id before ')' token
error: template argument 1 is invalid
Glad if someone would explain why or at least solve the problem. I'm using g++5.3 with --std=c++11 and windows 10.
EDIT: I just tested enum, under which circumstance errors still occurred, but with the first item on the error list removed. Tested int and everything went fine.