sfinae

Dependent non-type parameter packs: what does the standard say?

☆樱花仙子☆ 提交于 2019-12-05 04:10:33
I think the following code is well-formed: template< typename T > using IsSigned = std::enable_if_t< std::is_signed_v< T > >; template< typename T, IsSigned< T >... > T myAbs( T val ); Others say that it is ill-formed, because §17.7 (8.3) of the C++17 standard: Knowing which names are type names allows the syntax of every template to be checked. The program is ill-formed, no diagnostic required, if: (...) every valid specialization of a variadic template requires an empty template parameter pack , or (...) In my opinion IsSigned< T >... is a dependent template parameter, therefore it can not

SFINAE: detect existence of a template function that requires explicit specialization

淺唱寂寞╮ 提交于 2019-12-05 02:57:06
As a follow-up to my previous question , I am trying to detect the existence of a template function that requires explicit specialization. My current working code detects non-template functions (thanks to DyP's help), provided they take at least one parameter so that dependent name lookup can be used: // switch to 0 to test the other case #define ENABLE_FOO_BAR 1 namespace foo { #if ENABLE_FOO_BAR int bar(int); #endif } namespace feature_test { namespace detail { using namespace foo; template<typename T> decltype(bar(std::declval<T>())) test(int); template<typename> void test(...); } static

SFINAE enable_if explicit constructor

假装没事ソ 提交于 2019-12-05 02:41:50
I'm trying to switch between an explicit and an implicit conversion constructor via enable_if . My code currently looks like #include <type_traits> #include <cstdint> enum class enabled {}; template <bool B, typename T = void> using enable_if_t = typename std::enable_if<B, T>::type; template <bool B, typename T = void> using disable_if_t = typename std::enable_if<!B, T>::type; template <std::intmax_t A> struct SStruct { static constexpr std::intmax_t a = A; }; template <typename T> struct SCheckEnable : std::integral_constant<bool, T::a == 0> { }; template <typename U, typename T> class CClass

traits for testing whether func(args) is well-formed and has required return type

戏子无情 提交于 2019-12-05 01:56:54
问题 There are a number of similar questions/answers, but I couldn't quite put those answers together to serve my purposes. I want a traits template<typename Func, typename ReturnType, typename... Args> struct returns_a { static const bool value; }; such that returns_a<F,T,Args>::value is true if F(Args) is well formed and returns a T . After some more research, I got it working as follows: // value is true if Func(Args...) is well formed template<typename Func, typename... Args> class is_callable

How to extract the highest-indexed specialization from a structure?

亡梦爱人 提交于 2019-12-05 01:33:39
I'm trying to do some template metaprogramming and I'm finding the need to "extract" the highest index of a specialization of some structure in some type. For example, if I have some types: struct A { template<unsigned int> struct D; template<> struct D<0> { }; }; struct B { template<unsigned int> struct D; template<> struct D<0> { }; template<> struct D<1> { }; }; struct C { template<unsigned int> struct D; template<> struct D<0> { }; template<> struct D<1> { }; template<> struct D<2> { }; }; How can I then write a metafunction like this: template<class T> struct highest_index { typedef ???

Is there any guarantee on the order of substitution in a function template after type deduction?

老子叫甜甜 提交于 2019-12-05 01:06:20
Consider this function template: template<typename T> typename soft_error<T>::type foo(T, typename hard_error<T>::type) { } After deducing type T from the type of the first argument in the call to foo() , the compiler will proceed to substitute T and instantiate the function signature. If substitution for the return type gets executed first, causing a simple substitution failure, the compiler will discard this function template when computing the overload set and search for other viable overloads (SFINAE). On the other hand, if substitution for the second function parameter occurs first,

SFINAE away a copy constructor

旧街凉风 提交于 2019-12-05 01:03:26
Under certain conditions, I'd like to SFINAE away the copy constructor and copy assignment operator of a class template. But if I do so, a default copy constructor and a default assignment operator are generated. The SFINAE is done based on tags I pass as class template parameters. The problem is, that SFINAE only works on templates and a copy constructor/assignment operator can't be a template. Does there exist a workaround? stefan This solution uses a base class that is conditionally not copyable (by explicitely marking the copy constructor and copy assignment operator as deleted). template

enable_if with is_enum does not work

霸气de小男生 提交于 2019-12-05 00:53:56
问题 MCVE: #include <type_traits> template<typename T> bool func( typename std::enable_if< std::is_enum<T>::value, T >::type &t, int x ) { } enum class Bar { a,b,c }; int main() { Bar bar{Bar::a}; func(bar, 1); } I expect func(bar, 1); to match my definition of func however g++ reports: sfi.cc: In function 'int main()': sfi.cc:13:17: error: no matching function for call to 'func(Bar&, int)' func(bar, 1); ^ sfi.cc:13:17: note: candidate is: sfi.cc:4:10: note: template<class T> bool func(typename

SFINAE template specialization precedence

半腔热情 提交于 2019-12-04 23:04:10
#include <iostream> #include <array> #include <vector> template <typename T, typename SFINAE=void> struct trait; template <typename T> struct trait<T, decltype( std::declval<const T&>().begin(), std::declval<const T&>().end(), void() )> { static const char* name() { return "Container"; } }; template <typename T, std::size_t N> struct trait<std::array<T,N>> { static const char* name() { return "std::array"; } }; int main(int argc, char* argv[]) { std::cout << trait<std::vector<int>>::name() << std::endl; std::cout << trait<std::array<int,2>>::name() << std::endl; } I was expecting the third

Why is SFINAE causing failure when there are two functions with different signatures?

▼魔方 西西 提交于 2019-12-04 21:01:09
I was trying to wrap my head around this question here because it was written in such a way that it was hiding what it was actually doing. So I rewrote it as such: template<typename CLASS> struct has_begin { // NOTE: sig_matches() must come before fn_exists() as it is used for its // type. Also, no function bodies are needed as they are never called. // This matching sig results in a return type of true_type template<typename A_CLASS> static auto sig_matches(void(A_CLASS::*)()) -> std::true_type; // If the member function A_CLASS::begin exists and a sig_matches() function // exists with the