समस्या के बारे में और सोचने के लिए मेरे पास कुछ समय था (और इसके साथ आने के लिए एक अच्छा शराब)।
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");
यह है कि मैं क्या लेकर आए हैं
चेक_कॉन्सेप्ट टेम्पलेट विशेषज्ञता के बाद एक कॉन्स्टेक्स विधि में जोर दिया जाता है। टेम्पलेट क्लास परिभाषा में सीधे स्थिर आवेषण को एम्बेड करने से त्रुटि संदेश में संपूर्ण check_concept_impl रिकर्सन स्टैक खींच जाएगा।
तो (readibility के लिए छोड़े गए परिवर्तनों के बाकी) की तरह कुछ करने के लिए IsContainerCheck विशेषता को बदलने:
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");
उपज आप देख सकते हैं प्रत्येक पुनरावर्ती eval_if कॉल emended है होगा त्रुटि विवरण में जो खराब है क्योंकि यह त्रुटि संदेश और टेम्पलेट पैरामीटर के प्रकार से निर्भर त्रुटि संदेश बनाता है।
मुझे उम्मीद है कि जैसे ही टेम्पलेट तत्काल हो, चेक की आवश्यकता होगी, जिसके लिए जरूरी नहीं है कि किसी ऑब्जेक्ट का निर्माण किया जाए। – aschepler
काफी। कोशिश करने और व्यक्त करने के लिए बस संपादित किया गया। –
मैं बस उस पैरा को खरोंच कर दूंगा।मैंने सोचा कि मेरे पास एक गोचा था जिसने रैपर पर एक कन्स्ट्रक्टर कॉल की आवश्यकता थी, लेकिन मैं इसे आसान नहीं बना सकता, इसलिए यह मेरे कोड के साथ कुछ गलत है। –