C++ 基于条件模板的代码执行c++;

C++ 基于条件模板的代码执行c++;,c++,templates,boost,C++,Templates,Boost,所以我已经为此奋斗了一段时间,这也是我在这里的第一篇文章。我只是想知道,如果我传入的容器确实是boost中定义的前向容器,我如何编写代码,进一步检查代码是BackInsertionSequence还是FrontInsertionSequence,并根据其类型执行 template <class SequentialContainer> void MyClass<SequentialContainer>::SaySomething() { BOOST_CONCE

所以我已经为此奋斗了一段时间,这也是我在这里的第一篇文章。我只是想知道,如果我传入的容器确实是boost中定义的前向容器,我如何编写代码,进一步检查代码是BackInsertionSequence还是FrontInsertionSequence,并根据其类型执行

template <class SequentialContainer>
void MyClass<SequentialContainer>::SaySomething() {  
    BOOST_CONCEPT_ASSERT((boost::ForwardContainer<SequentialContainer>));  
    if (boost::BackInsertionSequence<SequentialContainer> == true) {  
        //do something  
    } else {  
        //say something else  
    }  
}
模板
void MyClass::SaySomething(){
BOOST_-CONCEPT_-ASSERT((BOOST::ForwardContainer));
如果(boost::BackInsertionSequence==true){
//做点什么
}否则{
//说点别的
}  
}

如果您像那里那样执行了
If
检查,则必须编译两个分支,而不管对于特定类型只有一个分支会被执行。这严重限制了一个简单的
(如果
)的实用性-您需要一个构造,使得只有一个分支能够编译

有两种常见的方法可以做到这一点。标签发送:

template <class SequentialContainer>
void MyClass<SequentialContainer>::SaySomething() {  
    SaySomething<SequentialContainer>(
        is_back_insertion_sequence<SequentialContainer>{}
    );
}

template <class SequentialContainer>
void SaySomething(std::true_type /* back insertion sequence */ ) { ... }

template <class SequentialContainer>
void SaySomething(std::false_type /* NOT back insertion sequence */ ) { ... }
模板
void MyClass::SaySomething(){
说点什么(
是返回插入序列{
);
}
模板
void SaySomething(std::true_type/*返回插入序列*/){…}
模板
void SaySomething(std::false_type/*非反向插入序列*/){…}
和SFINAE:

template <class SequentialContainer>
typename std::enable_if<
    is_back_insertion_sequence<SequentialContainer>::value
>::type
SaySomething() {
    /* back insertion sequence */
}

template <class SequentialContainer>
typename std::enable_if<
    !is_back_insertion_sequence<SequentialContainer>::value
>::type
SaySomething() {
    /* NOT back insertion sequence */
}
模板
typename std::启用\u如果<
是返回插入序列::值
>::类型
说点什么{
/*反向插入序列*/
}
模板
typename std::启用\u如果<
!是返回插入序列::值
>::类型
说点什么{
/*非反向插入序列*/
}

两者都有优点和缺点,但如果你只检查一个标志,那主要是意见的问题

下面是C++14纯粹在函数中执行编译时分支的尝试。我不知道这是不是个好主意

template<
  template<class...>class Test, class Arg,
  class F1, class F2,
  class=std::enable_if_t<
    Test<Arg>{}
  >
>
std::result_of_t< F1(Arg) > branch( Arg&& arg, F1&& f1, F2&& f2 ) {
  return std::forward<F1>(f1)(std::forward<Arg>(arg));
};
template<
  template<class...>class Test, class Arg,
  class F1, class F2,
  class=std::enable_if_t<
    !Test<Arg>{}
  >
>
std::result_of_t< F2(Arg) > branch( Arg&& arg, F1&& f1, F2&& f2 ) {
  return std::forward<F2>(f2)(std::forward<Arg>(arg));
};
模板<
模板类测试,类Arg,
F1级、F2级、,
class=std::如果<
测试{}
>
>
std::分支(Arg&&Arg,F1&&F1,F2&&F2)的结果{
返回std::forward(f1)(std::forward(arg));
};
模板<
模板类测试,类Arg,
F1级、F2级、,
class=std::如果<
!测试{}
>
>
std::分支(Arg&&Arg,F1&&F1,F2&&F2)的结果{
返回std::forward(f2)(std::forward(arg));
};
这是一个编译时分支。然后我们这样做:

template <class SequentialContainer>
void SaySomething() {
  branch<boost::BackInsertionSequence>( container,
  [&](auto&& container){ // true

  }, [&](auto&& container){ // false

  });
}
模板
空话{
分公司(集装箱、,
[&](自动和容器){//true
},[&](自动和容器){//false
});
}
这里我们测试
容器
,以确定它是否是
boost::BackInsertionSequence
。如果是这样,我们运行第一个分支,如果不是第二个分支


根据该标准,每个分支中的代码必须具有有效的专门化:这就是我传入容器的原因。我们可以假设被测试的容器在代码中具有我们想要的属性。

看看标记分派或SFINAE。您是否已经编写了一个带有命名运算符的版本来模拟静态if-then-else?有一个,但那不是我想的那个…@dyp-Ya,可能吧,但我不记得我写的所有东西,但这听起来很有道理。我可能只是画了个草图;再一次,关于它的奇怪细节看起来像是记忆,所以也许我把它写得很完整。不管怎样,名称操作符只是语法上的糖。要求自动lambda有一个有效的实例化是一个棘手的问题,基本上要求您的测试应用于传递给lambda的参数,这使得语法即使使用命名运算符也很难看。。。