C++ 非类型可变参数模板包不适用于宏函数

问题描述 投票:0回答:1

我下面有一个小例子,第一个运行正常,但第二个出现错误,我收到错误

no member named 'handle_func' in 'test_nontype_variadic'

工作示例:

class test_nontype_variadic{
    public:
        template<std::size_t... Sizes, typename UnaryFunction, typename... Args>
        auto handle_func(const std::source_location& sl, UnaryFunction&& unary_op, Args&&... args){
            /* do what needs to be done with Sizes... and sl*/
            return std::forward<UnaryFunction>(unary_op)(std::forward<Args>(args)...);
        }
};

//usage:
int main(){
    test_nontype_variadic test;
    int a = test.handle_func<4, 3, 5>(std::source_location::current(), [](auto a, auto b){return a + b;}, 10, 12);
    std::cout<<a<<std::endl;
}

但是,如果我使用宏为变量

sl
指定默认参数,它就会停止工作:

#define _CALLER_EXECUTE_FUNC ff_handle_execute_func
#define handle_func(...) _CALLER_EXECUTE_FUNC(std::source_location::current(), __VA_ARGS__)

class test_nontype_variadic{
    public:
        template<std::size_t... Sizes, typename UnaryFunction, typename... Args>
        auto _CALLER_EXECUTE_FUNC(const char* str, UnaryFunction&& unary_op, Args&&... args){
            /* do what needs to be done with Sizes...*/
            return std::forward<UnaryFunction>(unary_op)(std::forward<Args>(args)...);
        }


};

//usage:
int main(){
    test_nontype_variadic test;
    int a = test.handle_func<4, 3, 5>([](auto a, auto b){return a + b;}, 10, 12);
    std::cout<<a<<std::endl;
}

我收到错误:

error: no member named 'handle_func' in 'test_nontype_variadic'
        int a = test.handle_func<4, 3, 5>(__builtin_FUNCTION(), [](auto a, auto b){return a + b;}, 10, 12);
                ~~~~ ^
error: expected unqualified-id
        int a = test.handle_func<4, 3, 5>(__builtin_FUNCTION(), [](auto a, auto b){return a + b;}, 10, 12);
                                    ^
error: expected ';' at end of declaration
        int a = test.handle_func<4, 3, 5>(__builtin_FUNCTION(), [](auto a, auto b){return a + b;}, 10, 12);

但是,如果我要取出非类型可变参数模板,它会起作用:

#define _CALLER_EXECUTE_FUNC ff_handle_execute_func
#define handle_func(...) _CALLER_EXECUTE_FUNC(__builtin_FUNCTION(), __VA_ARGS__)

class test_nontype_variadic{
    public:
        template<typename UnaryFunction, typename... Args>
        auto _CALLER_EXECUTE_FUNC(const char* str, UnaryFunction&& unary_op, Args&&... args){
            /* do what needs to be done with Sizes...*/
            return std::forward<UnaryFunction>(unary_op)(std::forward<Args>(args)...);
        }


};

//usage:
int main(){
    test_nontype_variadic test;
    int a = test.handle_func(std::source_location::current(), [](auto a, auto b){return a + b;}, 10, 12);
    std::cout<<a<<std::endl;
}

效果很好。我想知道为什么,以及如何解决它。

c++ macros variadic-templates variadic-functions
1个回答
0
投票

语法:

test.handle_func<4, 3, 5>(

...尝试调用类似函数的宏

handle_func
,就像它是一个成员函数模板一样,但这显然是行不通的。 C++ 预处理器不知道类、成员和模板等内容。它只理解类似函数的宏。

它只是看到

handle_func < 4 ...
,其中
handle_func
未定义为非函数宏(因此不会发生宏替换),并且
<
是小于运算符。

解决方案

您可以使用自由函数语法

handle_func
:

#define handle_func(x, ...) (x)._CALLER_EXECUTE_FUNC(__builtin_FUNCTION(), __VA_ARGS__)

// ...

handle_func(test, [](auto a, auto b){return a + b;}, 10, 12);

话虽如此,目前尚不清楚为什么您首先需要宏。 如果您愿意使用类似的语法

test.call()([](auto a, auto b){return a + b;}, 10, 12);

...那么你就可以完全避免宏,因为

.call()
可以有一个参数

std::source_location loc = std::source_location::current();

... 和

.call()
可以返回一个带有重载调用运算符的函数对象,您可以将 lambda 及其参数输入其中。 唯一阻碍你并迫使你在这里使用宏的事情似乎是需要一些特定的调用语法。

© www.soinside.com 2019 - 2024. All rights reserved.