-1

suppose the following code:

#define __INIT_TYPE(type) { template<typename type>struct S{ };}

__INIT_TYPE(int);

int main(){
}

the second line produces the following error

Function definition for '\__INIT_TYPE' not found. Expected a declaration.
  1. Why does it happen? so far as I know the macro has to be replaced with the templated struct and which will be declared and then defined.

  2. If I am just missing something and there is a solution to q.1, is it considered a bad practice to nest types in the program with macros like this?

Captain Obvlious
  • 19,754
  • 5
  • 44
  • 74
  • 3
    If I try to expand out the use of your macro and add some line breaks, I get [this](https://godbolt.org/z/6jf3s9KMo), which doesn't make a lot of sense to me. `template`? What are the outermost brackets supposed to be doing? – Nathan Pierson Jan 02 '23 at 05:42
  • 4
    Obligatory reminder that identifiers containing `__` are reserved and shouldn't be used. – HolyBlackCat Jan 02 '23 at 05:45
  • What is the goal? Seems the purpose here is to define (near identical) explicit specialisations of a primary template. But why? C++ has mechanisms to specialise over a closed set of types without resorting to macros. – StoryTeller - Unslander Monica Jan 02 '23 at 06:37
  • goal of your MACRO is unclear... Multiple "typos" doesn't help. – Jarod42 Jan 02 '23 at 08:43
  • Forget the macro for a moment; just write the code that you want `__INIT_TYPE(int);` to produce and get that to work. Then, if you really, really, really want to use a macro, work backwards from the working code to create the macro. – Pete Becker Jan 02 '23 at 14:16

2 Answers2

2

In C++ avoid macros for as long as you can they are mostly bad practice. They are type unsafe and in general do not make code more readable (for other people). Just stick to standard C++ if you can.

In your case __INIT_TYPE is not initializing anything, only creating a template instance of S.

If you want an initialized instance of S Just make a function template that creates your struct.

template<typename type_t>
struct S 
{ 
};

template<typename> 
auto make_S()
{
    return S<typename type_t>{};
}

int main()
{
    auto s = make_S<int>();
}
Pepijn Kramer
  • 9,356
  • 2
  • 8
  • 19
  • That is the point I do want to have just the definition for the template and not initialized objects. I just want my macro to translate the first 4 lines of your code – Mark Tikhonov Jan 02 '23 at 05:44
  • I still don't really understand what you try to achieve with the macro. I would still give the same advise, just type : `templatestruct S{ };`. Because that is readable by anyone knowing C++ without having to lookup your macro. This has to do with code maintainability, don't use macros to just safe on a bit of typing. In any case do not start your macro with two underscores (reserved for library and compiler developers) – Pepijn Kramer Jan 02 '23 at 07:43
1

You defined the macros as a function with the body in braces, like a function body w/o a function name:

#define __INIT_TYPE(type) { template<typename type>struct S{ };}

Braces are not allowed outside functions. You might want

#define __INIT_TYPE(type) template<typename type>struct S{ };

Suggest that you take a look at What are the rules about using an underscore in a C++ identifier? to avoid further errors.

273K
  • 29,503
  • 10
  • 41
  • 64
  • I have just spotted that the code I wrote doesn't need to contain the typename keyword, however with the code provided by @273K the intellisense produces the following warning: // function definition for 'INIT_TYPE' not found. – Mark Tikhonov Jan 02 '23 at 05:52