Declaring class member with deduced type - c++

I have a code that uses type deduction like this:
template <typename... Ttypes>
Tuple<Ttypes...> makeTuple(Ttypes... args) {
Tuple<Ttypes...> result;
fillTuple<0>(result, args...);
return result;
}
I want to encapsulate the result to a class which is not a class template. The only way, and this is reasonable, is to have it as a static const member like this:
struct A {
static const auto t = makeTuple(1,2,3,'c');
};
and I get: error: in-class initializer for static data member of type 'const Tuple<int, int, int, char>' requires 'constexpr' specifier static const auto tuple = makeTuple(1,2,3,'c');.
If I use
struct A {
static const auto constexpr t = makeTuple(1,2,3,'c');
};
I get error: constexpr variable 'tuple' must be initialized by a constant expression.
Moreover, using constexpr is not good for me, because I' like to use non-literal types in a tuple.
Compiler Clang with -std=c++14.
Is there a way to get what I want?

Something along these lines, perhaps:
struct A {
using TupleType = decltype(makeTuple(1,2,3,'c'));
static const TupleType t;
};
// In a .cpp file
const A::TupleType A::t = makeTuple(1,2,3,'c');
Somewhat more elaborate, but avoids some repetition:
struct A {
static auto MakeMyTuple() { return makeTuple(1,2,3,'c'); }
using TupleType = decltype(MakeMyTuple());
static const TupleType t;
};
// In a .cpp file
const A::TupleType A::t = A::MakeMyTuple();
This way, arguments to makeTuple are all in one place.

You should be able to accomplish this without declaring the member static.
auto is useful for type deduction when it is also being initialized. If declaration is needed prior to initialization you can use decltype instead.
GeeksForGeeks has a good introduction to decltype.
https://www.geeksforgeeks.org/type-inference-in-c-auto-and-decltype/
#include <iostream>
#include <tuple>
#include <memory>
using namespace std;
template<typename... Types>
tuple<Types...> makeTuple(Types... types)
{
return tuple<Types...>();
}
//I'm using these two functions just to show
//that non constexpr functions can be used to determine type
int generateInt()
{
return 1;
}
char generateChar()
{
return 'a';
}
struct A
{
decltype(makeTuple(generateInt(), generateChar())) t;
A() : t(makeTuple(1, 'a'))
{
}
};
int main()
{
A a;
return 0;
}

Related

enum size and initialization of variable [duplicate]

Is there a way to convert an enum class field to the underlying type? I thought this would be automatic, but apparently not.
enum class my_fields : unsigned { field = 1 };
unsigned a = my_fields::field;
That assignment is being rejected by GCC. error: cannot convert 'my_fields' to 'unsigned int' in assignment.
I think you can use std::underlying_type to know the underlying type, and then use cast:
#include <type_traits> //for std::underlying_type
typedef std::underlying_type<my_fields>::type utype;
utype a = static_cast<utype>(my_fields::field);
With this, you don't have to assume the underlying type, or you don't have to mention it in the definition of the enum class like enum class my_fields : int { .... } or so.
You can even write a generic convert function that should be able to convert any enum class to its underlying integral type:
template<typename E>
constexpr auto to_integral(E e) -> typename std::underlying_type<E>::type
{
return static_cast<typename std::underlying_type<E>::type>(e);
}
then use it:
auto value = to_integral(my_fields::field);
auto redValue = to_integral(Color::Red);//where Color is an enum class!
And since the function is declared to be constexpr, you can use it where constant expression is required:
int a[to_integral(my_fields::field)]; //declaring an array
std::array<int, to_integral(my_fields::field)> b; //better!
You cannot convert it implicitly, but an explicit cast is possible:
enum class my_fields : unsigned { field = 1 };
// ...
unsigned x = my_fields::field; // ERROR!
unsigned x = static_cast<unsigned>(my_fields::field); // OK
Also mind the fact, that the semicolon should be after the closed curly brace in your enum's definition, not before.
With C++23 you'll finally get a library function for this:
std::to_underlying
It is already implemented in the standard libraries of GCC 11, Clang 13, and MSVC 19.30 (aka 2022 17.0).
Until you're able to use C++23 I recommend you (re)name any custom implementation to to_underlying and place it between a #if !defined(__cpp_lib_to_underlying) #endif block, which is the associated feature test macro. This way you can simply ditch the code at some point in the future when C++23 becomes available for you.
As others have pointed out there is no implicit cast, but you can use an explicit static_cast. I use the following helper functions in my code to convert to and from an enum type and its underlying class.
template<typename EnumType>
constexpr inline decltype(auto) getIntegralEnumValue(EnumType enumValue)
{
static_assert(std::is_enum<EnumType>::value,"Enum type required");
using EnumValueType = std::underlying_type_t<EnumType>;
return static_cast<EnumValueType>(enumValue);
}
template<typename EnumType,typename IntegralType>
constexpr inline EnumType toEnum(IntegralType value)
{
static_assert(std::is_enum<EnumType>::value,"Enum type required");
static_assert(std::is_integral<IntegralType>::value, "Integer required");
return static_cast<EnumType>(value);
}
template<typename EnumType,typename UnaryFunction>
constexpr inline void setIntegralEnumValue(EnumType& enumValue, UnaryFunction integralWritingFunction)
{
// Since using reinterpret_cast on reference to underlying enum type is UB must declare underlying type value and write to it and then cast it to enum type
// See discussion on https://stackoverflow.com/questions/19476818/is-it-safe-to-reinterpret-cast-an-enum-class-variable-to-a-reference-of-the-unde
static_assert(std::is_enum<EnumType>::value,"Enum type required");
auto enumIntegralValue = getIntegralEnumValue(enumValue);
integralWritingFunction(enumIntegralValue);
enumValue = toEnum<EnumType>(enumIntegralValue);
}
Usage code
enum class MyEnum {
first = 1,
second
};
MyEnum myEnum = MyEnum::first;
std::cout << getIntegralEnumValue(myEnum); // prints 1
MyEnum convertedEnum = toEnum(1);
setIntegralEnumValue(convertedEnum,[](auto& integralValue) { ++integralValue; });
std::cout << getIntegralEnumValue(convertedEnum); // prints 2
I find the following function underlying_cast useful when having to serialise enum values correctly.
namespace util
{
namespace detail
{
template <typename E>
using UnderlyingType = typename std::underlying_type<E>::type;
template <typename E>
using EnumTypesOnly = typename std::enable_if<std::is_enum<E>::value, E>::type;
} // namespace util.detail
template <typename E, typename = detail::EnumTypesOnly<E>>
constexpr detail::UnderlyingType<E> underlying_cast(E e) {
return static_cast<detail::UnderlyingType<E>>(e);
}
} // namespace util
enum SomeEnum : uint16_t { A, B };
void write(SomeEnum /*e*/) {
std::cout << "SomeEnum!\n";
}
void write(uint16_t /*v*/) {
std::cout << "uint16_t!\n";
}
int main(int argc, char* argv[]) {
SomeEnum e = B;
write(util::underlying_cast(e));
return 0;
}

Retrieving the underlying type of a c++11 enum [duplicate]

Is there a way to convert an enum class field to the underlying type? I thought this would be automatic, but apparently not.
enum class my_fields : unsigned { field = 1 };
unsigned a = my_fields::field;
That assignment is being rejected by GCC. error: cannot convert 'my_fields' to 'unsigned int' in assignment.
I think you can use std::underlying_type to know the underlying type, and then use cast:
#include <type_traits> //for std::underlying_type
typedef std::underlying_type<my_fields>::type utype;
utype a = static_cast<utype>(my_fields::field);
With this, you don't have to assume the underlying type, or you don't have to mention it in the definition of the enum class like enum class my_fields : int { .... } or so.
You can even write a generic convert function that should be able to convert any enum class to its underlying integral type:
template<typename E>
constexpr auto to_integral(E e) -> typename std::underlying_type<E>::type
{
return static_cast<typename std::underlying_type<E>::type>(e);
}
then use it:
auto value = to_integral(my_fields::field);
auto redValue = to_integral(Color::Red);//where Color is an enum class!
And since the function is declared to be constexpr, you can use it where constant expression is required:
int a[to_integral(my_fields::field)]; //declaring an array
std::array<int, to_integral(my_fields::field)> b; //better!
You cannot convert it implicitly, but an explicit cast is possible:
enum class my_fields : unsigned { field = 1 };
// ...
unsigned x = my_fields::field; // ERROR!
unsigned x = static_cast<unsigned>(my_fields::field); // OK
Also mind the fact, that the semicolon should be after the closed curly brace in your enum's definition, not before.
With C++23 you'll finally get a library function for this:
std::to_underlying
It is already implemented in the standard libraries of GCC 11, Clang 13, and MSVC 19.30 (aka 2022 17.0).
Until you're able to use C++23 I recommend you (re)name any custom implementation to to_underlying and place it between a #if !defined(__cpp_lib_to_underlying) #endif block, which is the associated feature test macro. This way you can simply ditch the code at some point in the future when C++23 becomes available for you.
As others have pointed out there is no implicit cast, but you can use an explicit static_cast. I use the following helper functions in my code to convert to and from an enum type and its underlying class.
template<typename EnumType>
constexpr inline decltype(auto) getIntegralEnumValue(EnumType enumValue)
{
static_assert(std::is_enum<EnumType>::value,"Enum type required");
using EnumValueType = std::underlying_type_t<EnumType>;
return static_cast<EnumValueType>(enumValue);
}
template<typename EnumType,typename IntegralType>
constexpr inline EnumType toEnum(IntegralType value)
{
static_assert(std::is_enum<EnumType>::value,"Enum type required");
static_assert(std::is_integral<IntegralType>::value, "Integer required");
return static_cast<EnumType>(value);
}
template<typename EnumType,typename UnaryFunction>
constexpr inline void setIntegralEnumValue(EnumType& enumValue, UnaryFunction integralWritingFunction)
{
// Since using reinterpret_cast on reference to underlying enum type is UB must declare underlying type value and write to it and then cast it to enum type
// See discussion on https://stackoverflow.com/questions/19476818/is-it-safe-to-reinterpret-cast-an-enum-class-variable-to-a-reference-of-the-unde
static_assert(std::is_enum<EnumType>::value,"Enum type required");
auto enumIntegralValue = getIntegralEnumValue(enumValue);
integralWritingFunction(enumIntegralValue);
enumValue = toEnum<EnumType>(enumIntegralValue);
}
Usage code
enum class MyEnum {
first = 1,
second
};
MyEnum myEnum = MyEnum::first;
std::cout << getIntegralEnumValue(myEnum); // prints 1
MyEnum convertedEnum = toEnum(1);
setIntegralEnumValue(convertedEnum,[](auto& integralValue) { ++integralValue; });
std::cout << getIntegralEnumValue(convertedEnum); // prints 2
I find the following function underlying_cast useful when having to serialise enum values correctly.
namespace util
{
namespace detail
{
template <typename E>
using UnderlyingType = typename std::underlying_type<E>::type;
template <typename E>
using EnumTypesOnly = typename std::enable_if<std::is_enum<E>::value, E>::type;
} // namespace util.detail
template <typename E, typename = detail::EnumTypesOnly<E>>
constexpr detail::UnderlyingType<E> underlying_cast(E e) {
return static_cast<detail::UnderlyingType<E>>(e);
}
} // namespace util
enum SomeEnum : uint16_t { A, B };
void write(SomeEnum /*e*/) {
std::cout << "SomeEnum!\n";
}
void write(uint16_t /*v*/) {
std::cout << "uint16_t!\n";
}
int main(int argc, char* argv[]) {
SomeEnum e = B;
write(util::underlying_cast(e));
return 0;
}

Resulting in an `error: incomplete type` while using std::tuple_size

I have a class template in a namespace
And I have a non member function inside that namespace which returns a std::tuple of std::shared_ptr(s)<myown::myclass<Type>>
I invoked the function F() and passed its result(std::tuple) to an another non-member function(inside myown namespace)
namespace myown {
template<typename T> class myclass{ /*...*/};
template<> class myclass<void>{ /*...*/};
auto F()
{
return std::make_tuple(std::shared_ptr<myclass<int>>(),
std::shared_ptr<myclass<const char *>>(),
std::shared_ptr<myclass<int>>());
}
template <typename tup>
auto anotherF(tup&& result){
size_t s = std::tuple_size<tup>::value;//
/*...*/
}
}
int main()
{
auto tr = myown::F();
myown::anotherF(tr);
}
Use of std::tuple_size<tup> results in error: incomplete type...used in nested name specifier
You need to decay the type to remove reference:
size_t s = std::tuple_size<std::decay_t<tup>>::value;

Declaring static auto function pointers in traits template

I have a couple of functions for different data types that I want to use in a template depending on the data type of the template parameter. I declared a helper template struct traits and specialized it for the corresponding data types.
My question is: is it possible to avoid writing the exact function signatures in these specializations? Additionally, is it possible to avoid defining these functions outside of the template declaration and still have them static?
The very simplified example of what I want to do is below. The syntax that I would like to use is commented out, but it clearly doesn't compile.
#include <iostream>
int f() { return 1; }
double g() { return 2.3; }
template<typename T>
struct traits;
template<>
struct traits<int> {
// static auto func = f;
int(*func)() = f;
};
template<>
struct traits<double> {
// static auto func = g;
double(*func)() = g;
};
template<typename T>
struct traits_user {
void output() {
// std::cout << traits<T>::func() << " ";
std::cout << traits<T>().func() << " ";
}
};
int main()
{
traits_user<int>().output();
traits_user<double>().output();
}
Edit
While answer by #RSahu is actually perfect, I cannot use it because I'm stuck with VS2013 for some time more. A solution suitable for VS2013 would be very welcome.
You can use:
static auto constexpr func = f;
and
static auto constexpr func = g;
I got the following error in g++ when I tried to compile without the constexpr.
g++ -std=c++11 -Wall socc.cc -o socc
socc.cc:17:24: error: ‘constexpr’ needed for in-class initialization of static data member ‘double (* traits<double>::func)()’ of non-integral type [-fpermissive]
static auto func = g;
Without support for constexpr, one work around is:
template<>
struct traits<int> {
static double func()
{
return f();
}
};
template<>
struct traits<double> {
static double func()
{
return g();
}
};
If you can't use auto, you can probably still use decltype and a type alias:
template<> struct traits<int> {
using F = decltype(&f);
const static F func;
};
const traits<int>::F traits<int>::func= f;
Whether that is better or worse than the explicit approach is for you to decide.
You can of course also omit the type alias, if you don't need it anywhere else:
template<> struct traits<int> {
const static decltype(&f) func;
};
const decltype(&f) traits<int>::func = f;

Turn casting / construction into a perfect forwardable function

SSCCE:
#include <functional>
using std::function;
using std::forward;
template<typename ToType, typename... FromTypes>
ToType construct(FromTypes&&... fromTypes) {
return ToType(forward<FromTypes>(fromTypes)...);
}
class Maybe {
public:
Maybe() : m_value(42.0f) {}
template<typename Function>
auto apply(Function function) const -> decltype(function(std::declval<float>())) {
return function(value());
}
private:
float const& value() const {
return m_value;
}
float m_value;
};
int main() {
Maybe a;
a.apply(construct<int, float>);
return 0;
}
Gives the error:
test.cpp: In instantiation of ‘decltype (function(declval<float>())) Maybe::apply(Function) const [with Function = int (*)(float&&); decltype (function(declval<float>())) = int]’:
test.cpp:31:32: required from here
test.cpp:17:28: error: invalid initialization of reference of type ‘float&&’ from expression of type ‘const float’
return function(value());
^
From the error message, it's obviously a problem with the fact that value() returns a const&.
The key point here, is that the type isn't being deduced on line 17, where value is being passed to it. The type is being assigned when the construct function is passed to apply on line 31.
I specified the wrong type to the template of construct. construct<int, float>. If I use construct<int, float const&> it functions just fine.
However, this is cumbersome and requires knowledge of the implementation of apply. And it will also never ever bind an lvalue, because T and T&& are different types. (Because of the lack of type deduction.)
Is there a way to have a function I can pass to another function and have type deduction occur at the site where it is called, so I can have perfect forwarding happen more or less transparently for the callers? Or is there another way to achieve this end that doesn't leak complexity to the caller?
How about this?
#include <functional>
using std::function;
using std::forward;
template<typename ToType>
class construct
{
public:
template<typename... FromTypes>
ToType operator()(FromTypes&&... fromTypes) {
return ToType(forward<FromTypes>(fromTypes)...);
}
};
class Maybe {
public:
Maybe() : m_value(42.0f) {}
template<typename Function>
auto apply(Function function) const -> decltype(function(std::declval<float>())) {
return function(value());
}
private:
float const& value() const {
return m_value;
}
float m_value;
};
int main() {
Maybe a;
a.apply(construct<int>());
return 0;
}
You only have to specify the type to which you want to convert to which obviously cannot be deduced in the context you have given.