Detect operator support with decltype/SFINAE

In C++11 the shortest most general solution I found was this one: #include <type_traits> template<class T, class = decltype(std::declval<T>() < std::declval<T>() )> std::true_type supports_less_than_test(const T&); std::false_type supports_less_than_test(…); template<class T> using supports_less_than = decltype(supports_less_than_test(std::declval<T>())); #include<iostream> struct random_type{}; int main(){ std::cout << supports_less_than<double>::value << std::endl; // prints ‘1’ std::cout << supports_less_than<int>::value << std::endl; // prints ‘1’ std::cout … Read more

What expressions yield a reference type when decltype is applied to them?

It is not easy to understand these concepts without getting formal. The primer probably does not want to confuse you and avoids introducing terms such as “lvalue“, “rvalue“, and “xvalue“. Unfortunately, these are fundamental in order to understand how decltype works. First of all, the type of an evaluated expression is never a reference type, … Read more

What does the void() in decltype(void()) mean exactly?

Using a hyperlinked C++ grammar, the parsing of decltype(void()) is: decltype( expression ) decltype( assignment-expression ) decltype( conditional-expression ) … lots of steps involving order of operations go here … decltype( postfix-expression ) decltype( simple-type-specifier ( expression-listopt ) ) decltype( void() ) So void() is a kind of expression here, in particular a postfix-expression. Specifically, … Read more

decltype as a return type in class member function

Is it valid? Your last example is well-formed, while the first one is not (so GCC is correct). Paragraph 3.4.1/7 on unqualified name lookup specifies: A name used in the definition of a class X outside of a member function body, default argument, brace-or- equal-initializer of a non-static data member, or nested class definition shall … Read more

Significance of parentheses in decltype((c))?

c is the name of a variable; (c) is an expression, in this case an lvalue expression, whose value is identical to the value of the variable c. And the two are treated differently by decltype. Consider, for example, decltype(1+2), which is also an example taking an expression. It just so happens that your example … Read more

What is decltype with two arguments?

It’s an comma-separated list of expressions, the type is identical to the type of the last expression in the list. It’s usually used to verify that the first expression is valid (compilable, think SFINAE), the second is used to specify that decltype should return in case the first expression is valid.

Arrow operator (->) in function heading

In C++11, there are two syntaxes for function declaration:     return-type identifier ( argument-declarations… ) and     auto identifier ( argument-declarations… ) -> return_type They are equivalent. Now when they are equivalent, why do you ever want to use the latter? Well, C++11 introduced this cool decltype thing that lets you describe type of an expression. So … Read more

decltype and parentheses

Just above that example, it says if e is an unparenthesized id-expression or a class member access (5.2.5), decltype(e) is the type of the entity named by e. if e is an lvalue, decltype(e) is T&, where T is the type of e; I think decltype(a->x) is an example of the “class member access” and … Read more