3

I am learning to use C++ 11 type_traits, in integral_constant, there is a function value_type();

I tried this but got error:

typedef std::integral_constant<int, 1> one_t;
one_t one_o;
one_o.value_type();

../src/main.cc:13:9: error: cannot refer to type member 'value_type' in 'one_t' (aka 'integral_constant') with '.'
one_o.value_type();

2 Answers 2

12

Well the function value_type() is not really a function with that name. Indeed, the definition of integral_constant looks like this:

template <class T, T v>
struct integral_constant {
    // ...
    typedef T value_type;
    constexpr operator value_type() const noexcept { return value; }
};

Notice that value_type is actually a typedef for the template parameter T (int, in OP's example). In addition there's a conversion operator that converts from integral_constant<T, v> to T. It's implicitly called like this

int i = one_o; // same as int i = 1;

To call it explicitly you need to use the operator keyword and the right type like this:

one_o.operator int();

which, thanks to the typedef member, is also equivalent to

one_o.operator one_t::value_type();
2
  • 2
    why provide operator value_type(), if static constexprT value = val; is already defined in template <typename T, T val>? @cassio-neri
    – athos
    Commented Dec 11, 2016 at 4:52
  • 1
    I think It's just for convenient, e.g., you can use bool b=std::true_type(), rather than bool b=std::true_type::value. @athos
    – expoter
    Commented Sep 25, 2020 at 4:46
1

If you want to create a temporary object of type int, then you should write like this.

typedef std::integral_constant<int, 1> one_t;
one_t one_o;
one_t::value_type();

If you meant operator value_type(), which is a conversion operator, then do it like this.

typedef std::integral_constant<int, 1> one_t;
one_t one_o;
int something = static_cast<value_type>(one_o);

Not the answer you're looking for? Browse other questions tagged or ask your own question.