Этот вопрос в духе последующий дальше от этого вопроса от другого пользователя, который имеет отличные ответы: Is it possible to write a template to check for a function's existence?Можно ли написать шаблон C++ для проверки существования конструктора?
Я хочу делать то, что описано в этом вопросе, за исключением того, я хочу, чтобы быть в состоянии сделать это для конструктора. Например, учитывая эти два типа:
class NormalType
{
public:
NormalType()
{
std::cout << "NormalType::NormalType()" << std::endl;
}
};
class SpecialType
{
public:
SpecialType()
{
std::cout << "SpecialType::SpecialType()" << std::endl;
}
SpecialType(int someArg)
{
std::cout << "SpecialType::SpecialType(int someArg)" << std::endl;
}
};
И это вспомогательная функция для построения объекта:
template<class T>
class ConstructHelper
{
public:
template<bool HasSpecialConstructor>
static T Construct()
{
return T();
}
template<>
static T Construct<true>()
{
return T(int(42));
}
};
Я хочу, чтобы иметь возможность писать код так:
NormalType normalType = ConstructHelper<NormalType>::Construct<has_special_constructor<NormalType>::value>();
SpecialType specialType = ConstructHelper<SpecialType>::Construct<has_special_constructor<SpecialType>::value>();
где желаемые результаты заключаются в том, что вызывается NormalType::NormalType()
, и вызывается . Недостающим компонентом здесь является тот критический has_special_constructor
помощник, который может определить, существует ли наш специальный конструктор для данного типа.
В предыдущем вопросе я ссылался на сделки с проверкой, существует ли данная функция для типа, и было представлено множество рабочих решений. К сожалению, большинство из них полагаются на возможность использовать адрес целевого метода, и в соответствии с спецификацией C++ вы не можете взять адрес конструктора (12.1.10). Из оставшихся рабочих решений все они, как представляется, полагаются на SFINAE с decltype на произвольное выражение в шаблонной специализации. Это простой способ решить эту проблему, но, к сожалению, я работаю над Visual Studio 2013, которая не поддерживает правила SFINAE C++ 11 и до сих пор не будет выпускать «Visual Studio 14» либо , При правильной поддержке SFINAE, я должен быть в состоянии сделать это, например:
template<class T>
struct has_special_constructor
{
template<class S>
struct calculate_value: std::false_type {};
template<>
struct calculate_value<decltype(T(int(42)))>: std::true_type {};
static const bool value = calculate_value<T>::value;
};
Но это не компилируется под VS2013, если я пытаюсь проверить тип, который не определяет мой целевой конструктор, из-за отсутствия поддержки SFINAE. Тем не менее, я еще не уверен, что это невозможно, я думаю, что может быть способ заставить его работать, но пока я не смог найти решение. Кто-нибудь есть способ сделать это, что я упустил?
Вот еще информация о том, что мне нужно для того, чтобы принять ответ в качестве решения этой проблемы:
Это должно быть возможным разрешить
has_special_constructor<T>::value
для любого заданного типа без дополнительного кода записывается для этого конкретного типа.Я в первую очередь ориентирован на Visual Studio 2013, поэтому любое решение должно работать в этой среде. Я знаю, что полностью соответствующий C++ 11 компилятор может справиться с этой проблемой более легко, но я ищу что-то, что может теперь функционировать в текущем целевом компиляторе.
Если кто-нибудь может предоставить решение, которое работает в компиляторе C++ 03 (IE, без каких-либо возможностей C++ 11), я соглашусь с тем, что использует возможности C++ 11.
В этот момент я бы согласился на временное обходное решение на основе расширения MSVC, так как я могу использовать препроцессор, чтобы вернуться к этому методу, пока не появится полная поддержка C++ 11.
Hah! Просто как тот! Мне нужно снова пройти список черт типа C++ 11 и передать их в память, я думаю. Я просто потратил 3 часа на поиск решения этой проблемы. –
За бонусные баллы * (ну, не совсем, но я бы, если бы мог!) Любая идея, если std :: is_constructible может быть эмулирован в компиляторе C++ 03? –
@RogerSanders См. Мое редактирование. Я считаю, что для этого вам нужно выражение SFINAE, которое является * видом * C++ 03, я думаю. –