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

auto type deduction for argument with default value

很抱歉没有足够的时间进行深入调查,而是依靠您的帮助。

考虑简单的代码:

#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++ 会触发错误:

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:

我想我需要把我的问题说清楚才不会被

弄错

这里的重点不是将 auto 传递给函数,而是将 auto 与参数的 默认值 结合使用,未考虑在上述问题中。

编辑 2:

正如此处评论中所阐明的,C++11 没有将 auto 作为参数传递的功能,但是 C++14 及更高版本(g++ 6.3.1 默认为“gnu++14 “) 好像。不过,我最初的问题与 C++11 无关,我的问题不是 C++11 是否支持 auto 参数。我依赖 auto 作为参数,但忘记仔细检查它的最低标准版本。很抱歉,我现在已经解决了这个问题。

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

我希望它能清楚我的问题和 Is auto as a parameter in a regular function a GCC 4.9 extension? 之间的区别。如果没有请告诉我。

没有,it is a non-deduced context

Non-deduced contexts.

In the following cases, the types, templates, and non-type values that are used to compose P do not participate in template argument deduction, but instead use the template arguments that were either deduced elsewhere or explicitly specified. If a template parameter is used only in non-deduced contexts and is not explicitly specified, template argument deduction fails.

<...>

4) A template parameter used in the parameter type of a function parameter that has a default argument that is being used in the call for which argument deduction is being done

Should I be able to declare a function parameter as auto while still being able to give it a default value in C++11 or C++14?

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

I thought the given default value would be enough to let compiler deduce the parameter type...

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

内容如下

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;
    }
}

我知道:是多余的。

-- 编辑--

OP 说

I was just wondering if I couldn't make my code more readable by not repeating

可能不是更具可读性,但是...如果您不希望它重复...我知道宏是提炼出来的邪恶但是...如果您真的想要避免重复。 ..

#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;
    }
}

或者(如果你想在参数的基础上使用技巧)

#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;
    }
}