Why statements cannot appear at namespace scope?
The expression p++
which you've written is at namespace scope. It is forbidden by the grammer of namespace-body which is defined in §7.3.1/1 as:
namespace-body:
declaration-seqopt
which says the namespace-body can optionally contain only declaration. And p++
is surely not a declaration, it is an expression, therefore the Standard implicitly forbids it. The Standard might have explicit statement forbidding this, but I think the above should be enough.
In the same way, you cannot do this:
namespace sample
{
f(10,10); //error
std::cout << "hello world" << std::endl;//error
}
But if you somewhow convert expressions into declarations (or rather use expressions in declarations), then you could evaluate the so-called expressions. Here is one trick:
#include<iostream>
namespace sample
{
struct any { template<typename T> any(const T&){} };
void f(int a,int b) { std::cout << a * b << std::endl; }
any a1= (f(10,10), 0); //ok
any a2 = std::cout << "hello world" << std::endl;//ok
}
int main() {}
Output (if you're lucky):
100
hello world
Online demo : http://ideone.com/icbhh
Notice that the return type of f()
is void
, which means I cannot write the following (see error):
any a1 = f(10,10); //error
That is why I used comma operator so that the expression could have some value, which evaluates to the last operand in the comma expression. In case of std:cout
, since it returns std::ostream&
, I don't need to use comma operator; it is fine without it.
One more interesting thing in the above code: why I defined any
and a templated constructor in it? The answer is, I wrote this so that I could assign value of any type (no pun intended), be it int
, std::ostream&
or whatever. The templated constructor can take argument of any type.
But don't write such code. They're not guaranteed to work the way you expect.
Read the answers in this topic where you would see why such coding could be dangerous:
- Is main() really start of a C++ program?
Why block scope at global namespace is not allowed?
I am curious as to why creating a block scope {} outside any function (in global scope) is not permitted.
It would be pointless and misleading. Variables declared outside any function are statically allocated so never go out of scope (except at the end of the program).
Edit: to make a variable exist transiently on program startup, you can do something like:
static auto throwaway_name = [] () { MyClass myVar; return 0; } ();
The only thing this allocates statically is an int
(which might get optimised out, I'm not sure).
Why can't I declare a concept at class scope?
The fundamental difficulty that would arise is that concepts could become dependent:
template<class T>
struct A {
template<T::Q X>
void f();
};
Is X
a non-type template parameter of (dependent) type T::Q
(which does not require typename
in C++20), or is it a type template parameter constrained by the concept T::Q
?
The rule is that it’s the former; we would need new syntax (along the lines of typename
/template
) to express the other possibility: perhaps something like
template<T::concept Q X> requires T::concept R<X*>
void A::g() {}
No one has explored such an extension seriously, and it could easily conflict with other extensions to concept syntax that might be more valuable.
Using variables defined in an anonymous namespace in another namespace
CListName = "ListName";
is a statement (specifically, it's an assignment expression, which is an expression statement).
A statement cannot appear at namespace scope; you need to put the statement into a function.
a template declaration cannot appear at block scope (template class in main)
Since u didn't write a constructor for A
, I supposed u want to use the inherited one, hence u have to provide the following line in A
using List<T>::List;
And since u used c++11
, u have to provide the template arg
, as follows
A<int> a(10);
If u want to make the compiler figure it out, use c++17
or c++20
and provide the following guide
template<class T> A(T)-> A<T>;
Now the full code with c++17
will be
template<typename T>
class List
{
public:
List(T) {}
};
template<typename T>
class A: public List<T>
{
public:
using List<T>::List;
};
template<class T> A(T)-> A<T>;
int main()
{ //No problem here...!
A a(10);
}
And with c++11
will be
template<typename T>
class List
{
public:
List(T) {}
};
template<typename T>
class A: public List<T>
{
public:
using List<T>::List;
};
int main()
{ //No problem here...!
A<int> a(10);
}
template declaration cannot appear at block scope
In your
template <class T>
SimpleVector<T>::SimpleVector(int s)
there is a mismatch of opening and closing braces for the for
loop at the last.
And in the destructor, you should clear the vector as aptr->clear();
, because aptr
is a pointer variable.
Related Topics
On How to Recognize Rvalue or Lvalue Reference and If-It-Has-A-Name Rule
Serializing Opencv Mat_<Vec3F>
Is the Behavior of Subtracting Two Null Pointers Defined
Why Is Std::Iterator Deprecated
Is There C/C++ Equivalent of Eval("Function(Arg1, Arg2)")
How to Use a C++ Smart Pointers Together with C's Malloc
How to Declare Variables of Different Types in the Initialization of a for Loop
How to Enable Experimental C++11 Concurrency Features in Mingw
Differencebetween C-Like Casting and Functional Casting
Warning: Returning Reference to Temporary
How to Implement Timeout for Function in C++
How to Generate Random Numbers in C++
Multiple Implicit Conversions on Custom Types Not Allowed
Critique My Non-Intrusive Heap Debugger