Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/135.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ C/C+中的句法糖+;_C++_C_Syntax_Metaprogramming_Syntactic Sugar - Fatal编程技术网

C++ C/C+中的句法糖+;

C++ C/C+中的句法糖+;,c++,c,syntax,metaprogramming,syntactic-sugar,C++,C,Syntax,Metaprogramming,Syntactic Sugar,我一直在研究Ruby,发现它的关键字“直到”和“除非”非常有趣。所以我想什么是一个好方法来添加类似的关键字到C/C++。这就是我想到的: #define until(x) while(!(x)) #define unless(x) if(!(x)) 我正在寻找一些关于这方面的建议。有人能提出更好的选择吗 下面是我编写的一个程序示例,用于说明我打算做什么: #include <stdio.h> #include <stdlib.h> #define until

我一直在研究Ruby,发现它的关键字“直到”和“除非”非常有趣。所以我想什么是一个好方法来添加类似的关键字到C/C++。这就是我想到的:

#define until(x)    while(!(x))
#define unless(x)   if(!(x))
我正在寻找一些关于这方面的建议。有人能提出更好的选择吗

下面是我编写的一个程序示例,用于说明我打算做什么:

#include <stdio.h>
#include <stdlib.h>

#define until(x)    while(!(x))
#define unless(x)   if(!(x))

unsigned int factorial(unsigned int n) {
    unsigned int fact=1, i;
    until ( n==0 )
        fact *= n--;
    return fact;    
}

int main(int argc, char*argv[]) {
    unless (argc==2)
        puts("Usage: fact <num>");
    else {
        int n = atoi(argv[1]);
        if (n<0)
            puts("please give +ve number");
        else
            printf("factorial(%u) = %u\n",n,factorial(n));
    }
    return 0;
}
#包括
#包括
#定义直到(x)而(!(x))
#定义除非(x)如果(!(x))
无符号整数阶乘(无符号整数n){
无符号整数事实=1,i;
直到(n==0)
事实*=n--;
返回事实;
}
int main(int argc,char*argv[]){
除非(argc==2)
puts(“用法:事实”);
否则{
int n=atoi(argv[1]);
如果(n)
有人能提出更好的选择吗

是的。完全不要这样做。直接使用
while
if
语句即可


<>当你在C或C++编程时,C++或C++中的程序,而<>代码>直到和<代码>,除非在某些语言中经常使用和惯用,它们不是C或C++。

< P>我建议最好不要使用它们。 您不能在Ruby样式中使用它们

`printf("hello,world") unless(a>0);`
这是违法的


对于C程序员来说,理解代码会更加困难。同时,额外的宏可能是一个问题。

如果要定义宏,最好让它们看起来很难看。特别是,它们应该都是大写字母,并且有某种前缀。这是因为没有名称空间,也没有协调h类型系统或过载解决方案C++ + < /P> 因此,如果您的宏在
之前被称为
BIGYAN\u不必要的\u macro\u,那么它将不会完全“超越苍白”

如果您想用新的循环结构扩展C++,请考虑在C++ 0x中研究lambdas,在这里您可以允许:

until([&] { return finished; }, [&] 
{
    // do stuff
});

它并不完美,但比宏更好。

这让我想起了我在某人的代码中看到的一些东西:

#define R return;

此外,使代码难以理解,会增加维护成本。

如果宏仅用于 您自己的代码库。 你可能会感兴趣。 也就是说,当我们在C++中使用宏时,我看到了宏的一些缺点。 例如,我们不能写为:

until (T* p = f(x)) ...
unless (T* p = f(x)) ...
while (T* p = f(x)) ...
if (T* p = f(x)) ...
另一方面,我们可以这样写:

until (T* p = f(x)) ...
unless (T* p = f(x)) ...
while (T* p = f(x)) ...
if (T* p = f(x)) ...
对于
,除非
,如果我们将其定义为:

#define unless(x) if (x) {} else
然后我们可以写
,除非(T*p=f(x))…
。但是,在这种情况下,我们不能
在它后面添加
else
子句。

看看boostforeach是如何完成的

标头定义BOOST_FOREACH(丑陋的、带前缀的宏)。 你可以

在你的.cpp文件,以便有更干净的代码。 但是,您不应该在.h文件中这样做,而应该使用丑陋的BOOST\u FOREACH

现在,这里有一组“函数编程”宏,用于“方便”IF-THEN-ELSE表达式(因为?:很难看):

现在

intx=IF(y==0)1

否则,如果(y你这样做的方式在我看来是正确的,如果你真的要这么做的话。因为宏的扩展与你期望的[1]非常相似,我认为让宏看起来像syntax(),而不是通常推荐的吓人的大写宏()用于表明此代码不遵循常规语法,您应该谨慎使用

[1] 唯一的缺陷是无法声明变量,这无论如何都是不可能的,并且在错误使用时可能在正确的位置产生错误,而不是做一些奇怪的事情

此外,即使是可读性的微小提高也很重要,因此能够说
until(
而不是
while(!
)确实可以更容易地读取许多循环。如果结束条件更容易被认为是一种例外条件(不管它是否是)这样写循环使阅读更容易。因此,即使它只是句法糖,我认为还是有理由考虑的。

但是我认为这不值得。好处很小,因为大多数程序员都习惯于阅读
if(!
成本是真实的:任何阅读代码的人都必须检查这是一个宏还是一个自定义编译器,以及它是否按照他们的想法运行。这可能会误导你认为你可以做类似于
i=5的事情,除非xxxx;
。这种小小的改进,如果广泛使用,会使语言变得碎片化,因此通常最好这样做以标准的方式处理问题,并慢慢地采取改进措施

但是,它可以做得很好:Boost和Tr1的整体,特别是模板所做的东西,看起来像是对库的扩展,涉及到C++以各种方式扩展,其中很多都没有被采纳,因为它们似乎不值得,但其中很多都有很小的或非常广泛的卷取,因为它们确实有了改进。yntax糖示例(IMHO):

structfoo{
无效条(){}
};
typedef std::vector FooVector;
typedef boost::ptr_向量FooPtrVector;
食物载体v1;
for(FooVector::iterator it=v1.begin();it!=v1.end();++it)
(*it)->bar();//丑陋
FooPtrVector v2;
for(FooPtrVector::iterator it=v2.begin();it!=v2.end();++it)
it->bar();//很好

正如人们所说,添加这些单词并不能真正提供有用的语法糖分,因为阅读一段时间(或一个if(!的代价很小,所有C开发人员都习惯了),使用这样的宏会吓坏大多数C开发人员。此外,让一种语言看起来像另一种语言也不是一个好主意

P>但是,语法糖。正如已经说过的,在C++中,通过模板来增加语法糖的添加,STL也提供SMOME糖(例如,<代码> STD::MaMuxGub(A,B)< /C> >是一个语法糖,用于<代码> STD::配对(A,B)< /C> > 随着语言的改进,功能性和语法性都被添加,以提高开发人员的可读性、可写性和效率
int x = IF(y==0) 1
        ELSE IF(y<0) 2*y
        ELSE 3*y;
int x = (y==0) ? 1 : (y<0) ? 2*y : 3*y;
struct Foo {
    void bar() {}
};
typedef std::vector<Foo*> FooVector;
typedef boost::ptr_vector<Foo> FooPtrVector;

FooVector v1;
for (FooVector::iterator it = v1.begin(); it != v1.end(); ++it)
    (*it)->bar(); // ugly

FooPtrVector v2;
for (FooPtrVector::iterator it = v2.begin(); it != v2.end(); ++it)
    it->bar(); // nice
//C++ < 11
std::vector<int> v;
v.push_back(3);
v.push_back(7);
v.push_back(9);
v.push_back(12);
for (std::vector<int>::iterator it = v.begin();
     it != v.end();
     it++)
{
    std::cout << *it << std::endl;
}
//C++ >= 11
std::vector<int> v {3, 7, 9, 12};

for (auto elm : v)
{
    std::cout << elm << std::endl;
}
f :: IO String
f =
  ask "What's your name ?" >>= \name ->
  putStrLn "Write something." >>= \_ ->
  getLine >>= \string ->
  putStrLn ("Hello " ++ name ++ " you wrote " ++ string) >>= \_ ->
  return name

g :: IO String    
g = do
  name <- ask "What's your name ?"
  putStrLn "Write something."
  string <- getLine
  putStrLn ("Hello " ++ name ++ " you wrote " ++ string)
  return name