首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >具有默认值的参数的自动类型推导

具有默认值的参数的自动类型推导
EN

Stack Overflow用户
提问于 2017-04-26 19:58:04
回答 2查看 1.3K关注 0票数 3

我为没有足够的时间进行深入的调查和依靠你的帮助而道歉。

考虑一下简单的代码:

代码语言:javascript
复制
#include <iostream>

enum class PrintColour
{
    COLOUR_1        =   0,
    COLOUR_2        =   1,
};
 
void colour( auto c = PrintColour::COLOUR_1 )
{
    switch ( c )
    {
        case PrintColour::COLOUR_1:
            std::cout << "Colour 1" << std::endl;
            break;
        case PrintColour::COLOUR_2:
            std::cout << "Colour 2" << std::endl;
    }
}

int main( )
{
//  colour( ); couldn't deduce template parameter ‘auto:1’
    colour( PrintColour::COLOUR_1 );    // Fine!
}

这段代码与编译和运行完全一样,没有问题。但是,如果取消对colour( );的注释,g++会触发错误:

代码语言:javascript
复制
auto_param.cpp: In function ‘int main()’:
auto_param.cpp:27:10: error: no matching function for call to ‘colour()’
  colour( );
          ^
auto_param.cpp:13:6: note: candidate: template<class auto:1> void colour(auto:1)
 void colour( auto c = PrintColour::COLOUR_1 )
      ^~~~~~
auto_param.cpp:13:6: note:   template argument deduction/substitution failed:
auto_param.cpp:27:10: note:   couldn't deduce template parameter ‘auto:1’
  colour( );
          ^

这可能是我错过了一个愚蠢的观点,也可能是我真的很愚蠢,误解了整件事。

我是否应该将一个函数参数声明为auto,同时仍然能够在C++11或C++14中给它一个默认值?

我认为给定的默认值足以让编译器推断参数类型.

编辑1:

它认为我需要把我的问题说得更清楚,这样在C++中是否有一种将auto作为参数传递的方法?就不会弄错了

这里的要点不是将auto传递给函数,而是将auto与参数的默认值结合在一起,这在前面的问题中没有考虑。

编辑2:

正如这里的注释所阐明的,C++11没有将auto作为参数传递的特性,但是C++14和on (g++ 6.3.1默认为"gnu++14")似乎是这样的。不过,我最初的问题与C++11无关,我的问题也不是C++11是否支持auto参数。我依赖auto作为参数,但忘记了检查它的最低标准版本。我很抱歉我现在解决了这个问题。

代码语言:javascript
复制
g++ -std=c++11 auto_param.cpp -o auto_param
auto_param.cpp:13:14: error: use of ‘auto’ in parameter declaration only available with -std=c++14 or -std=gnu++14

我希望我的问题和在常规函数中,auto作为参数是否是GCC 4.9的扩展?之间的区别是清楚的。如果没有请告诉我。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2017-04-26 20:35:20

我是否应该将一个函数参数声明为auto,同时仍然能够在C++11或C++14中给它一个默认值?

我不知道C++17是否支持它,但据我所知,C++11和C++14不支持函数的auto参数(C++14只支持lambda函数)

我认为给定的默认值足以让编译器推断参数类型.

如果您接受使用模板类型而不是auto,则还必须添加默认模板类型。

如下所示

代码语言:javascript
复制
template <typename T = decltype(PrintColour::COLOUR_1)>
void colour( T c = PrintColour::COLOUR_1 )
{
    switch ( c )
    {
        case PrintColour::COLOUR_1:
            std::cout << "Colour 1" << std::endl;
            break;
        case PrintColour::COLOUR_2:
            std::cout << "Colour 2" << std::endl;
    }
}

我知道:是多余的。

-编辑--

行动小组说

我只是在想,如果我不能通过不重复来提高代码的可读性

更易读不过..。如果你不想重复..。我知道宏是被蒸馏出来的邪恶但是..。如果你真的想避免重复..。

代码语言:javascript
复制
#define noRepeat(r, n, a, b) \
r n (decltype(b) a = b)

noRepeat(void, colour, c, PrintColour::COLOUR_1)
{
    switch ( c )
    {
        case PrintColour::COLOUR_1:
            std::cout << "Colour 1" << std::endl;
            break;
        case PrintColour::COLOUR_2:
            std::cout << "Colour 2" << std::endl;
    }
}

或者也可以(如果你想在参数的基础上玩这个把戏)

代码语言:javascript
复制
#define parDef(a, b)  decltype(b) a = b

void colour ( parDef(c, PrintColour::COLOUR_1), parDef(d, 5) )
{
    switch ( c )
    {
        case PrintColour::COLOUR_1:
            std::cout << "Colour 1" << std::endl;
            break;
        case PrintColour::COLOUR_2:
            std::cout << "Colour 2" << std::endl;
    }
}
票数 2
EN

Stack Overflow用户

发布于 2017-04-26 20:05:44

不,这是一个非推断的上下文。

非推导上下文. 在以下情况下,用于组成P的类型、模板和非类型值不参与模板参数的推导,而是使用在其他地方推导或显式指定的模板参数。如果模板参数仅在非推导上下文中使用,且未显式指定,则模板参数演绎失败。 <...> 4)在函数参数的参数类型中使用的模板参数,该参数具有一个默认参数,该参数用于正在对其进行参数推导的调用中。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/43643473

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档