나는이 문제에 대해 더 많이 생각할 시간이 있었다.
namespace _details {
struct PassedCheck {
constexpr static int printError() {
return 0; //no error concept check passed
}
};
template<template<typename> class ConceptCheck, typename ...ModelTypes>
struct check_concept_impl;
template<template<typename> class ConceptCheck, typename FirstType, typename ...ModelTypes>
struct check_concept_impl<ConceptCheck, FirstType, ModelTypes...> : mpl::eval_if< typename ConceptCheck<FirstType>::type,
check_concept_impl<ConceptCheck, ModelTypes...>,
mpl::identity<ConceptCheck<FirstType>>>
{ };
template<template<typename> class ConceptCheck, typename LastType>
struct check_concept_impl<ConceptCheck, LastType> : mpl::eval_if<typename ConceptCheck<LastType>::type,
mpl::identity<PassedCheck>,
mpl::identity<ConceptCheck<LastType>>>
{ };
}
template<template<typename> class ConceptCheck, typename ...ModelTypes>
struct check_concept {
private:
typedef typename _details::check_concept_impl<ConceptCheck, ModelTypes...>::type result_type;
public:
// the constexpr method assert produces shorter, fixed depth (2) error messages than a nesting assert in the trait solution
// the error message is not trahsed with the stack of variadic template recursion
constexpr static int apply() {
return result_type::printError();
}
};
template<typename ContainerType>
struct IsContainerCheck : is_container<ContainerType>
{
template<typename BoolType = false_t>
constexpr static int printError() {
static_assert(BoolType::value, "Type is not a container model");
return 0;
}
};
및 사용 :
이
check_concept<IsContainerCheck, std::vector<int>, std::vector<int>, float, int>::apply();
이 솔루션은 아마 가장 우아한 아니다 그러나 나는이 짧은 어설 메시지 유지 :
In file included from ../main.cpp:4:0: ../constraint.check.hpp: In instantiation of ‘static constexpr int IsContainerCheck::printError() [with BoolType = std::integral_constant; ContainerType = float]’: ../constraint.check.hpp:61:34: required from ‘static constexpr int check_concept::apply() [with ConceptCheck = IsContainerCheck; ModelTypes = {std::vector >, std::vector >, float, int}]’ ../main.cpp:25:83: required from here ../constraint.check.hpp:74:3: error: static assertion failed: Type is not a container model static_assert(BoolType::value, "Type is not a container model");
를이 내가 생각 해낸 것입니다
assert는 check_concept 템플릿 전문화가 완료된 후 constexpr 메소드에서 발행됩니다. 정적 어서 트를 템플릿 클래스 정의에 직접 포함 시키면 전체 check_concept_impl 재귀 스택을 오류 메시지로 끌어다 놓을 수 있습니다. 각 재귀 eval_if 호출이 emended되어 볼 수 있듯이
template<typename ContainerType>
struct IsContainerCheck
{
static_assert(is_container<ContainerType>::type::value, "Type is not a container model");
};
오류
../constraint.check.hpp: In instantiation of ‘struct IsContainerCheck’: ../constraint.check.hpp:36:9: required from ‘struct _details::check_concept_impl’ /usr/include/boost/mpl/eval_if.hpp:38:31: required from ‘struct boost::mpl::eval_if, _details::check_concept_impl, boost::mpl::identity > > >’ ../constraint.check.hpp:36:9: required from ‘struct _details::check_concept_impl >, float, int>’ /usr/include/boost/mpl/eval_if.hpp:38:31: required from ‘struct boost::mpl::eval_if, _details::check_concept_impl >, float, int>, boost::mpl::identity > > >’ ../constraint.check.hpp:36:9: required from ‘struct _details::check_concept_impl >, std::vector >, float, int>’ ../constraint.check.hpp:53:84: required from ‘struct check_concept >, std::vector >, float, int>’ ../main.cpp:25:81: required from here ../constraint.check.hpp:72:2: error: static assertion failed: Type is not a container model static_assert(is_container::type::value, "Type is not a container model");
를 얻을 것이다 :
그래서 (일기 좋게 생략 변화의 나머지)처럼 뭔가에 IsContainerCheck 형질 변경 오류 메시지가 템플리트 매개 변수의 양과 유형에 종속적이 G로 오류 설명에 좋지 않습니다.
필자는 템플릿이 인스턴스화 되 자마자 검사가 수행되기를 기대합니다. 이는 반드시 개체가 생성 될 필요는 없습니다. – aschepler
그렇습니다. 그냥 시도하고 표현하기 위해 편집했습니다. –
나는 단지 그 파라를 긁을 것이다.래퍼에서 생성자 호출을 필요로하는 문제가 있다고 생각했지만 간단하게 만들 수는 없으므로 코드에 문제가있을 수 있습니다. –