C++模板类型演绎问题

ham*_*mcn 4 c++ templates

动机:我想创建一个实用程序类,而不必写:

if( someVal ==  val1 || someVal == val2 || someVal == val3 )
Run Code Online (Sandbox Code Playgroud)

我可以写:

if( is(someVal).in(val1, val2, val3) )
Run Code Online (Sandbox Code Playgroud)

这更接近于数学'a是(b,c,d)'的元素,并且当变量名'someVal'很长时也会节省大量的输入.

这是我到目前为止的代码(2和3值):

template<class T>
class is {
private:
    T t_;
public:
    is(T t) : t_(t) { }

    bool in(const T& v1, const T& v2) { 
        return t_ == v1 || t_ == v2; 
    }
    bool in(const T& v1, const T& v2, const T& v3) { 
        return t_ == v1 || t_ == v2 || t_ == v3; 
    }
};
Run Code Online (Sandbox Code Playgroud)

但是,如果我写,它无法编译:

is(1).in(3,4,5);
Run Code Online (Sandbox Code Playgroud)

相反,我必须写

is<int>(1).in(3,4,5);
Run Code Online (Sandbox Code Playgroud)

这不是太糟糕,但如果编译器能够弄清楚类型是否int我必须明确指定它会更好.
反正有没有做到这一点,或者我坚持明确指定它?

fa.*_*fa. 14

如果要保留此语法,可以使用辅助函数,如:

template<class T>
class is_op {
private:
    T t_;
public:
    is_op(T t) : t_(t) { }

    bool in(const T& v1, const T& v2) { 
        return t_ == v1 || t_ == v2; 
    }
    bool in(const T& v1, const T& v2, const T& v3) { 
        return t_ == v1 || t_ == v2 || t_ == v3; 
    }
};


template< class U >
inline is_op<U> is( U const& v )
{
    return is_op<U>( v );
}

int main(int argc, char* argv[])
{
    is( 1 ).in( 1 , 2 , 4 );
}
Run Code Online (Sandbox Code Playgroud)


Mat*_* M. 5

这个问题非常有趣,布尔条件可能会变得毛茸茸.

我自己倾向于喜欢编写特殊功能,因为这里的含义很难传达.什么:

if (someVal == val1 || someVal == val2 || someVal == val3)
Run Code Online (Sandbox Code Playgroud)

意思?

if ( is(someval).in(val1, val2, val3) )
// or
if ( is(someval).in(val1)(val2)(val3) ) // implements short-circuiting
                                        // and removes arity issue
                                        // using a proxy object
Run Code Online (Sandbox Code Playgroud)

更好?

我认为阅读更容易:

bool isToBeLogged(const Foo& foo)
{
  // Either
  static std::set<Foo> ValuesToLog = /* some boost assign magic or whatever */;
  return ValuesToLog.find(foo) != ValuesToLog.end();

  // Or
  return foo == val1 || foo == val2 || foo == val3;
}


if (isToBeLogged(someVal))
Run Code Online (Sandbox Code Playgroud)

我想这是一个风格问题.

第二种方法的优点包括:

  • 如果测试不止一次,逻辑不会四处散乱(因此更改很容易)
  • 无需评论测试,方法名称已经完成

不健康?我想这更像打字......哦,好吧:p