c++ - Defining member variable using decltype on variadic function template of a class template -


i trying use 'decltype' on variadic function template return value type , use define member variable. keep getting error:

d:\qt projects\opengl_physicssim\lib\physics effects\include\particlelist.hpp:89: error: cannot convert 'std::tuple<std::uniform_real_distribution<double>, std::uniform_real_distribution<double>, std::uniform_real_distribution<double> >' 'int' in assignment      distributiontuple = createdistribution<type, types...>(meanvalue, meanvalues..., variancevalue, variancevalues...); 

basically, decltype fails , declare distributiontuple int rather deduce return type of createdistribution.

template<typename attributetype, typename type, typename ...types> class particleattributegenerator { private:  template<typename t>  auto createdistribution(t meanvalue, t variancevalue)  {    static_assert(      std::is_integral<type>::value || std::is_floating_point<type>::value,      "type should either integral value or floating point value");     using disttype = typename std::conditional< std::is_integral<t>::value,                                                std::uniform_int_distribution<>,                                                std::uniform_real_distribution<> >::type;    t = meanvalue - variancevalue;    t b = meanvalue + variancevalue;     return std::tuple<disttype>(disttype(a,b));  }   template<typename tfirst, typename ...trest>  auto createdistribution(tfirst meanvalue, trest... meanvalues, tfirst variancevalue, trest... variancevalues)  {    static_assert(      std::is_integral<type>::value || std::is_floating_point<type>::value,      "type should either integral value or floating point value");     using disttype = typename std::conditional< std::is_integral<tfirst>::value,                                                std::uniform_int_distribution<>,                                                std::uniform_real_distribution<> >::type;    tfirst = meanvalue - variancevalue;    tfirst b = meanvalue + variancevalue;     static_assert((sizeof...(meanvalues)) == (sizeof...(variancevalues)), "number of meanvalues , variancevalues should match!");     return std::tuple_cat(std::tuple<disttype>(disttype(a,b)), createdistribution<trest...>(meanvalues..., variancevalues...));  }  public:  particleattributegenerator(type meanvalue, types... meanvalues, type variancevalue, types... variancevalues)  {    distributiontuple = createdistribution<type, types...>(meanvalue, meanvalues..., variancevalue, variancevalues...);  // 89 : error            }  private:   //using result_type_t = typename std::result_of<createdistribution(type, types..., type, types...)>::type;   decltype (createdistribution<type, types...>(type, types..., type, types...)) distributiontuple;   //decltype (createdistribution<type, types...>(0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f)) distributiontuple; }; 

it works when provide values of arguments of createdistribution, not behavior looking for. since don't know how many parameters there function, has stay variadic template function.

example of how plan use class template:

particleattributegenerator<glm::vec3, float, float, float> example1(3.0f, 1.0f, 3.0f, 1.0f, 3.0f, 1.0f); particleattributegenerator<glm::u8vec4, uint8_t, uint8_t, uint8_t, uint8_t> example2(3, 2, 25, 5, 51, 12, 32, 3); 

if don't have member variable , use distributedtuple as:

auto distributiontuple = createdistribution<type, types...>(meanvalue, meanvalues..., variancevalue, variancevalues...); 

it compiles, therefore believe createdistribution manages define tuple recursively. no use me. there must wrong missing. use gcc 4.9.2 in -std=c++14 mode.

first off, let's massively simplify example down more manageable less external stuff:

template <typename t> class bar { private:     template <typename u>     auto foo(u a, u b)     {         return std::tuple<u>(a+b);     }  public:     bar(t a, t b)     {         distributiontuple = foo<t>(a, b);     }  private:     decltype (foo<t>(t, t)) distributiontuple; };  int main() {     bar<int> b(4, 4); } 

this gives me sample compile error present in question (cannot convert std::tuple<int> int. that's because:

foo<t>(t, t) 

isn't valid function call. need call foo<t> expressions have types. not list of types. that, have std::declval. is:

foo<t>(std::declval<t>(), std::declval<t>()) 

once make change, you'll new compile error: "cannot call member function foo without object." let's add object declval again. following compiles:

template <typename t> class bar { private:     template <typename u>     auto foo(u a, u b)     {         return std::tuple<u>(a+b);     }  public:     bar(t a, t b)     {         distributiontuple = foo<t>(a, b);     }  private:     decltype(std::declval<bar>().foo<t>(                  std::declval<t>(),                   std::declval<t>())              ) distributiontuple; }; 

Comments

Popular posts from this blog

1111. appearing after print sequence - php -

java - WARN : org.springframework.web.servlet.PageNotFound - No mapping found for HTTP request with URI [/board/] in DispatcherServlet with name 'appServlet' -

Ruby on Rails, ActiveRecord, Postgres, UTF-8 and ASCII-8BIT encodings -