Ho un problema nella mia applicazione in cui vorrei affermare che un'applicazione di compilazione sarebbe stata rifiutata dal compilatore. C'è un modo per controllare questo con SFINAE?Come verificare in fase di compilazione che un'espressione è illegale?
Ad esempio, supponiamo che mi piacerebbe convalidare che std::transform
in un intervallo const
non è valido. Ecco cosa ho finora:
#include <algorithm>
#include <functional>
#include <iostream>
namespace ns
{
using std::transform;
template<typename Iterator1, typename Iterator2, typename UnaryFunction>
struct valid_transform
{
static Iterator1 first1, last1;
static Iterator2 first2;
static UnaryFunction f;
typedef Iterator2 yes_type;
typedef struct {yes_type array[2];} no_type;
static no_type transform(...);
static bool const value = sizeof(transform(first1, last1, first2, f)) == sizeof(yes_type);
};
}
int main()
{
typedef int *iter1;
typedef const int *iter2;
typedef std::negate<int> func;
std::cout << "valid transform compiles: " << ns::valid_transform<iter1,iter1,func>::value << std::endl;
std::cout << "invalid transform compiles: " << ns::valid_transform<iter1,iter2,func>::value << std::endl;
return 0;
}
Sfortunatamente, il mio tratto respinge sia i casi legali che quelli illegali. Il risultato:
$ g++ valid_transform.cpp
$ ./a.out
valid transform compiles: 0
invalid transform compiles: 0
'constexpr' potrebbe aiutare, solo un pensiero veloce. – chris
L'altro problema è che 'std :: cout << sizeof (std :: transform (iter1(), iter1(), iter2(), func()));' compila, mentre 'std :: cout << std :: transform (iter1(), iter1(), iter2(), func()); 'no. – Lol4t0
@ Lol4t0 Questo perché 'sizeof()' non valuta i suoi argomenti durante la compilazione. – TemplateRex