Как я могу определить время компиляции, если у класса есть конструктор с данной сигнатурой? Чтобы быть конкретным, я хотел бы сделать следующее:

class Archive
{
    // (...)

    template <typename T>
    T Read()
    {
        if constexpr(HasUnarchiveConstructor<T>())
        {
            return T(*this); // constructor accepts reference to Factory
        }
        else
        {
            T t;
            Unarchive(*this, t); // use stand alone function instead. (if this is not available either, compiling fails)
            return t;
        }
    }
}

Существует множество источников для обнаружения функций с определенными сигнатурами. Однако я не могу преобразовать их в конструкторы. источник 1 источник 2 источник 3 и другие.

Из найденных источников я скомпилировал следующее, чтобы определить, есть ли у функции оператор плюс:

template<typename T>
using HasUnarchiveConstructorImpl = decltype(std::declval<T>() + std::declval<T>());

template< typename T >
using HasUnarchiveConstructor = std::is_detected<HasUnarchiveConstructorImpl, T>;

Как я могу распространить это на проверку, которую я хочу выполнить? Или как я могу сделать это по-другому?

1
Aart Stuurman 24 Апр 2017 в 13:24

2 ответа

Лучший ответ

Как я могу распространить это на проверку, которую я хочу выполнить?

Вы можете использовать decltype(...) в выражении T{...} следующим образом:

struct Foo 
{ 
    Foo(Archive&) { }
};

struct Bar
{ 
    // unsupported
};

template<class T>
using HasUnarchiveConstructorImpl = 
    decltype(T{std::declval<Archive&>()});

template <class T>
using HasUnarchiveConstructor = 
    std::experimental::is_detected<HasUnarchiveConstructorImpl, T>;

static_assert(HasUnarchiveConstructor<Foo>::value);
static_assert(!HasUnarchiveConstructor<Bar>::value);

живой пример на wandbox


Или как я могу сделать это по-другому?

См. ответ Говарда Хиннанта.

1
Community 23 Май 2017 в 12:02

Я хотел бы использовать:

if constexpr(std::is_constructible<T, Archive&>{})

Эта черта живет в <type_traits> и поставляется готовой и отлаженной для вас. Существует целое семейство черт, чтобы обнаружить варианты этого вопроса, доступные для вас там.

11
Howard Hinnant 24 Апр 2017 в 13:59