mercredi 30 décembre 2020

How to check in C++ that identifier is declared?

I want to check at some point of code if some identifier x is declared, how do I do that?

I need this kind of check for different types of identifiers - variables, enum constants, functions, types, macros, etc. But for start I want to check at least variables and functions.

I need such kind of check (e.g. imaginary declared(x)) so that next code works e.g. for the case of int variable x:

if constexpr(declared(x)) {
    int y = x + 1;
} else {
    std::cout << "Variable 'x' not declared!" << std::endl;
}

For the case of macros of cause I can use #ifdef x, but how to do same check for variables/functions?

For the case of global non-lambda functions I figured out next code, based on overloaded functions resolution, but it needs using helper macros-based global definitions (can it be simplified more?):

Try it online!

#include <iostream>
#include <type_traits>

#define declared_func_helper(x, ...) \
    struct NotDeclared; \
    template <typename ... Args> \
    NotDeclared x(Args ...); \
    template <typename ... Args> \
    inline constexpr bool declared_func_##x(Args && ... args) { \
        return !std::is_same_v<decltype(x(args...)), NotDeclared>; \
    }

// declare some of functions
//void f(int a) {}
void g(bool b, char c) {}
    
// define helpers before or after declared functions
declared_func_helper(f);
declared_func_helper(g);

int main() {
    // check declaration of functions
    std::cout << "func 'f' declared: " << std::boolalpha << declared_func_f(int()) << std::endl;
    std::cout << "func 'g' declared: " << std::boolalpha << declared_func_g(bool(), char()) << std::endl;
}

which outputs:

func 'f' declared: false
func 'g' declared: true

For the case of non-global variables I implemented next code, but it also needs helpers definition through macroses:

Try it online!

#include <type_traits>
#include <iostream>

#define declared_var_helper(x) \
    struct NotDeclared_##x {}; \
    NotDeclared_##x x;
#define declared_var(x) \
    ([&](){ return !std::is_same_v<decltype(x), NotDeclared_##x>; }())
    
// use helpers before variables declaration
declared_var_helper(x);
declared_var_helper(y);

int main() {
    // declare some of variables
    //bool x = false;
    int y = 0;
    // ........
    // later check declaration
    constexpr bool is_declared_x = declared_var(x), is_declared_y = declared_var(y);
    std::cout << std::boolalpha << "var 'x' declared: " << is_declared_x << std::endl;
    std::cout << "var 'y' declared: " << is_declared_y << std::endl;
}

which outputs:

var 'x' declared: false
var 'y' declared: true

What about other cases, or easier ways to check?





Aucun commentaire:

Enregistrer un commentaire