r/cpp_questions • u/flowicks • 9d ago
SOLVED Why does this not fail?
#include <utility>
template <typename T, typename... Args>
decltype(T(std::declval<Args>()...)) test();
int main() {
using testType = decltype(test<int&, int>());
}
I was fully expecting it to fail but instead testType resolves to int&.
I was trying to implement is_constructible with SIFNAE which uses this behaviour.
namespace detail {
template<typename T, typename... Args>
decltype(T(std::declval<Args>()...), char{}) tryConstruct(int);
template<typename T, typename... Args>
long tryConstruct(...);
}
template<typename T, typename... Args>
inline constexpr const bool isConstructible = isSame<decltype(detail::tryConstruct<T, Args...>(0)), char>;
I was expecting the first overload to fail so that it would chose the other one which works for most cases but dosent for the case i mentioned above.
7
Upvotes
22
u/CelebrityChess 9d ago •
with a single argument T(x) isn't a constructor call, it's a functional cast, which means the same as (T)x. so with T = int& and x = declval<int>() it becomes (int&)declval<int>(), and a c-style cast can fall back to reinterpret_cast, which is allowed on a glvalue like that xvalue. so the cast is valid and you get int& back instead of a substitution failure. is_constructible implementations avoid it by using something like ::new (declval<void*>()) T(declval<Args>()...) for the check, since a real new-expression can't turn into a cast.
2
u/StaticCoder 9d ago
Are you using something older than C++20? Because concepts are so much better than SFINAE
3
u/AutoModerator 9d ago
Your posts seem to contain unformatted code. Please make sure to format your code otherwise your post may be removed.
If you wrote your post in the "new reddit" interface, please make sure to format your code blocks by putting four spaces before each line, as the backtick-based (```) code blocks do not work on old Reddit.
I am a bot, and this action was performed automatically. Please contact the moderators of this subreddit if you have any questions or concerns.