3

It all seemed simple.

Shouldn't has_member_type::value be true for T=vector in my code below? Sorry if it had already be answered. I looked for a while, but couldn't find an answer.

#include <iostream>
#include <type_traits>

// has_value_type
template <typename, typename = std::void_t<>>
struct  has_value_type: std::false_type {};

template <typename T>
struct has_value_type<T, std::void_t<typename T::value_type>>: std::true_type {};

int main()
{
    std::cout << "bool: " << std::boolalpha << has_value_type<bool>::value << std::endl;
    std::cout << "vector_has: " << std::boolalpha << has_value_type<std::vector<int>>::value << std::endl;

    std::cout << "true_type: " << std::boolalpha << std::true_type::value << std::endl;
    std::cout << "false_type: " << std::boolalpha << std::false_type::value << std::endl;
    return 0;
}

Output:

bool: false
vector_has: false
true_type: true
false_type: false

I'm using clang++

clang version 9.0.0 (tags/RELEASE_900/final)
Target: x86_64-apple-darwin17.7.0
Thread model: posix
  • 6
    Your example doesn't `#include ` - If that is indeed what reproduces the error on your end, then that would be the culprit. Perhaps there is only a forward declaration introduced by another header. And so, the trait is querying an incomplete type. Meaning it *doesn't* have any members. – StoryTeller - Unslander Monica Aug 06 '20 at 17:50

1 Answers1

6

If you use the libc++ standard library implementation, and don't include <vector>, then a forward declaration of std::vector is introduced with:

#include <iostream> // forward declares std::vector

demo

This forward declaration allows the code to compile, but the sfinae check returns false since there are no member types defined for std::vector yet.

You can't rely on this, and should always #include<vector> if you want to use std::vector in any context.

cigien
  • 57,834
  • 11
  • 73
  • 112