Sunday, 4 June 2017

c++ - Function works when not in namespace else it breaks

Answer


The following code compiles:



#include "List.h"
//namespace prototypeInd{namespace templates{ //Uncomment for error
template
inline void static_for(const Lambda& f,std::integral_constant) {
static_for(f, std::integral_constant());

f(std::integral_constant());
}

template
inline void static_for(const Lambda& f, std::integral_constant) {
f(std::integral_constant());
}
//}} //Uncomment for error
//using namespace prototypeInd::templates; //Uncomment for error
template

using ic = std::integral_constant;
typedef List,ic<1>,ic<2>,ic<3>,ic<4>,ic<5>,ic<6>,ic<7> > list;
int main(int argc,char** args){
static_for([](auto i){ std::cout << list::IndexOf() << std::endl; },list::SizeOf());
}


But as soon as you uncomment the marked lines it gives a huge whopper of an error.



Here is List.h:




template
struct SizeOf_ : std::integral_constant() + 1>{};
template
struct SizeOf_ : std::integral_constant { };

template
struct Index_{
static_assert(index < SizeOf_(), "Index is outside of bounds");
typedef typename Index_::value value;

};
template
struct Index_<0,First, Rest...>{
typedef First value;
};
template
struct List{
template
using IndexOf = typename Index_::value;
typedef SizeOf_ SizeOf;

};


This seems inexplicable....A namespace should not change the function of the code?!?!?!? (or should it?).



I am using g++ with std=c++14....Any help is appreciated



Why does having a namespace change anything?







When Alf compiles this code with g++ 5.1.0 and removes the out-commenting, that compiler reports as first error that




foo.cpp:11:5: error: static assertion failed: Index is outside of bounds
static_assert(index < SizeOf_(), "Index is outside of bounds");


The complete diagnostics avalanche for that first error:





foo.cpp: In instantiation of 'struct Index_<18446744073709551615ull, std::integral_constant, std::integral_constant, std::integral_constant, std::integral_constant, std::integral_constant, std::integral_constant, std::integral_constant, std::integral_constant >':
foo.cpp:21:64: required by substitution of 'template template using IndexOf = typename Index_::value [with long long unsigned int i = i; First_t = std::integral_constant; Rest_t = {std::integral_constant, std::integral_constant, std::integral_constant, std::integral_constant, std::integral_constant, std::integral_constant, std::integral_constant}]'
foo.cpp:52:38: required from 'main(int, char**):: [with auto:1 = std::integral_constant]'
foo.cpp:33:15: recursively required from 'void prototypeInd::templates::static_for(const Lambda&, std::integral_constant) [with long long unsigned int N = 7ull; Lambda = main(int, char**)::]'
foo.cpp:33:15: required from 'void prototypeInd::templates::static_for(const Lambda&, std::integral_constant) [with long long unsigned int N = 8ull; Lambda = main(int, char**)::]'
foo.cpp:52:90: required from here
foo.cpp:11:5: error: static assertion failed: Index is outside of bounds
static_assert(index < SizeOf_(), "Index is outside of bounds");
^

No comments:

Post a Comment

c++ - Does curly brackets matter for empty constructor?

Those brackets declare an empty, inline constructor. In that case, with them, the constructor does exist, it merely does nothing more than t...