SFINAE doesn't detect T::reference
The std::vector<T>
class is a model of the STL Container concept, and as such any proper implementation of vector has to include a nested typedef value_type
as well as reference
. This should be detectable using SFINAE. However, in my own tests, I can use SFINAE to detect a nested value_type
typedef, but for some reason I can't detect reference
.
template <class T>
typename T::value_type* test(T)
{
cout << "Has nested typedef!" << endl;
}
template <class T> 开发者_如何学编程
void test(...)
{
cout << "Doesn't have nested typedef!" << endl;
}
int main()
{
test(std::vector<int>());
}
This outputs: Has nested typedef!
However, if I replace value_type
with reference
, like:
template <class T>
typename T::reference* test(T)
{
cout << "Has nested typedef!" << endl;
}
template <class T>
void test(...)
{
cout << "Doesn't have nested typedef!" << endl;
}
int main()
{
test(std::vector<int>());
}
...the program fails to compile at all, giving the error: error: no matching function for call to test(std::vector<int, std::allocator<int> >)
Why does the SFINAE technique work with T::value_type
but not with T::reference
?
What's a pointer to a reference?
A: Impossible. Pointers to references cannot exist, so neither of your functions can exist. This is in contrast to your first case, where at least one of the functions can exist (and thus you get compilation, linkage and output).
Interestingly, SFINAE is working here, as the function definition is not causing the compilation error. It's attempting to call a function that, because of impossibility+SFINAE, doesn't exist, that's causing the error. :)
typename T::reference* test(T)
Pointers to references are illegal in C++.
§8.3.2/4 from the Standard says:
There shall be no references to references, no arrays of references, and no pointers to references.
精彩评论