C++11 有没有办法在编译时打印constexpr字符串?

C++11 有没有办法在编译时打印constexpr字符串?,c++11,C++11,我正在尝试执行以下操作(仅限于下面代码的相关部分): 模板 结构IsContainerCheck:是否为容器 { 静态constexpr char*err_value=“类型不是容器模型”; }; 名称空间检查概念{ 模板 结构运行{ constexpr static int apply(){ 静态\u断言(false,IsContainerCheck::err\u值) 返回0; } }; 模板 结构运行{ constexpr static int apply(){ 返回0; } }; } 这

我正在尝试执行以下操作(仅限于下面代码的相关部分):

模板
结构IsContainerCheck:是否为容器
{
静态constexpr char*err_value=“类型不是容器模型”;
};
名称空间检查概念{
模板
结构运行{
constexpr static int apply(){
静态\u断言(false,IsContainerCheck::err\u值)
返回0;
}
};
模板
结构运行{
constexpr static int apply(){
返回0;
}
};
}
这会失败,因为静态_断言只允许打印文本。BOOST\u STATIC\u ASSERT\u MSG宏也是如此

所以我的问题是-在编译期间是否有任何方法输出constexpr字符串? 如果有一个gcc扩展提供此功能,那也将非常好


使用的编译器gcc 4.8.1

gcc不提供您想要的机制。然而,您将不需要 如果您能够像中所示的那样对代码进行重构,那么它将非常有用 下面的节目。(我已经填补了一些空白,以便给我们一个机会 可编译示例):

#包括
#包括
模板
结构是一个容器
{
静态布尔常量值=false;
};
模板
结构是一个容器
{
静态布尔常量值=真;
};
模板
struct IsContainerCheck/:is_container我花了一些时间(和一杯好酒一起)来思考这个问题。这就是我想到的:

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;
    }
};
namespace\u详细信息{
结构通过检查{
constexpr static int printError(){
返回0;//未通过错误概念检查
}
};
模板
结构检查\u概念\u实施;
模板
如果
{ };
模板
结构检查\u概念\u实现:mpl::eval\u如果
{ };
}
模板
结构检查概念{
私人:
typedef typename\u details::check\u concept\u impl::type result\u type;
公众:
//constexpr方法assert比trait解决方案中的嵌套assert生成更短的固定深度(2)错误消息
//错误消息不会与可变模板递归堆栈一起传递
constexpr static int apply(){
返回结果类型::printError();
}
};
模板
结构IsContainerCheck:是否为容器
{
模板
constexpr static int printError(){
静态断言(BoolType::value,“类型不是容器模型”);
返回0;
}
};
以及用法:

check_concept<IsContainerCheck, std::vector<int>, std::vector<int>, float, int>::apply(); 
检查概念::应用();
该解决方案可能不是最优雅的,但我认为它使断言消息保持简短:

在../main.cpp:4:0中包含的文件中: ../constraint.check.hpp:在“static constexpr int IsContainerCheck::printError()[with BoolType=std::integral_constant;ContainerType=float]”的实例化中: ../constraint.check.hpp:61:34:从“static constexpr int check_concept::apply()[with ConceptCheck=IsContainerCheck;ModelTypes={std::vector>,std::vector>,float,int}]中需要 ../main.cpp:25:83:此处为必填项 ../constraint.check.hpp:74:3:错误:静态断言失败:类型不是容器模型 静态断言(BoolType::value,“类型不是容器模型”)

在完成check_概念模板专门化之后,在constexpr方法中发出assert。将静态断言直接嵌入模板类定义会将整个check\u concept\u impl递归堆栈拖到错误消息中

因此,将IsContainerCheck特性更改为类似(为便于阅读,省略了其余更改):

模板
结构IsContainerCheck
{
静态_断言(是_容器::类型::值,“类型不是容器模型”);
};
会产生一个错误

../constraint.check.hpp:在“struct IsContainerCheck”的实例化中: ../constraint.check.hpp:36:9:从'struct\u details::check\u concept\u impl'中需要 /usr/include/boost/mpl/eval_if.hpp:38:31:必须来自“struct boost::mpl::eval_if,_details::check_concept\u impl,boost::mpl::identity>>>” ../constraint.check.hpp:36:9:从'struct\u details::check\u concept\u impl>,float,int>中需要 /usr/include/boost/mpl/eval_if.hpp:38:31:必须来自“struct boost::mpl::eval_if,_details::check_concept\u impl>,float,int>,boost::mpl::identity>>” ../constraint.check.hpp:36:9:从'struct\u details::check\u concept\u impl>,std::vector>,float,int>中需要 ../constraint.check.hpp:53:84:从'struct check_concept>,std::vector>,float,int>中需要 ../main.cpp:25:81:此处为必填项 ../constraint.check.hpp:72:2:错误:静态断言失败:类型不是容器模型 静态_断言(是_容器::类型::值,“类型不是容器模型”)


正如您可以看到的,每个递归eval_if调用都在错误描述中进行了校正,这是错误的,因为它使错误消息依赖于模板参数的数量和类型。

我希望在模板实例化后立即进行检查,这并不一定需要构造任何对象,我只需要划掉这一段。我以为我有一个问题,需要在包装器上调用构造函数,但我不能让它变得简单,所以我的代码肯定有问题。@Mike嗨,Mike,我在下面发布了我想出的解决方案。你的建议似乎还可以,所以我接受你的建议。
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(); 
template<typename ContainerType>
struct IsContainerCheck
{
static_assert(is_container<ContainerType>::type::value, "Type is not a container model");
};