vscode-cpptools icon indicating copy to clipboard operation
vscode-cpptools copied to clipboard

c++17 partial template specialization

Open isv75 opened this issue 6 years ago • 10 comments

Hello,

Intellisense seems to have trouble selecting the correct partial template specialization, reporting the error "Incomplete type is not allowed". The following code compiles using gcc --std=c++17:

int func(const char *t, int x) {
    return x;
}

template<auto TFunc>
struct S;

template<class TResult, class... TArgs, TResult TFunc(TArgs...)>
struct S<TFunc> {
    static TResult invoke(TArgs ...args) {
        return TFunc(args...);
    }
};

int main() {
    return S<&func>::invoke("test", 42);
}

Regards, Ivar Svendsen.

isv75 avatar Jan 04 '20 00:01 isv75

Thanks for reporting this. I've filed a bug on VS at https://developercommunity.visualstudio.com/content/problem/875098/cc-intellisense-error-incomplete-type-is-not-allow.html .

Repros with msvc and gcc modes.

sean-mcmanus avatar Jan 04 '20 01:01 sean-mcmanus

Also, adding code

int func()
{
	return 0;
}

causes the additional error at the same spot

"cannot deduce 'auto' template parameter type \"auto\" from \"<unknown-type>\"",

Might be the same root cause.

sean-mcmanus avatar Jan 06 '20 19:01 sean-mcmanus

The original repro looks to have been addressed in 1.0.0. However, adding:

int func()
{
	return 0;
}

after the original repro code still causes the same 2 errors. I suspect this has something to do with multiple definitions of func() at global scope. It should not be ambiguous, as there is only 1 yet declared where used. This is likely related to issues with failing to flag use-before-declaration as an error: https://github.com/microsoft/vscode-cpptools/issues/4901

Colengms avatar Apr 13 '21 01:04 Colengms

Seems that the issue appears when adding multiple template specializations

template <auto F>
struct S;
template <typename T, typename R, typename... Args, R (T::*F)(Args...)>
struct S<F> {};
template <typename T, typename R, typename... Args, R (T::*F)(Args...) const>
struct S<F> {};

The template specialization with const-qualified member pointer triggers the incomplete type is not allowed error, however the compilation is successful (as it should be). Example:

struct TestStruct
{
   void testMethod() {}
   void testConstMethod() const {}
};

int main()
{
    S<&TestStruct::testMethod> a;
    S<&TestStruct::testConstMethod> b; // <- Triggers `incomplete type is not allowed` but compiles successfully
}

This issue persists both when the specialization has members and when it does not

switch-blade-stuff avatar Jun 04 '21 23:06 switch-blade-stuff

@SoftwareEngIsArt The example code doesn't compile for me. What compiler and args are you using?

sean-mcmanus avatar Jun 05 '21 00:06 sean-mcmanus

@sean-mcmanus To compile the testing code i used Clang 11.0.1 with -O3 -std=gnu++17

switch-blade-stuff avatar Jun 05 '21 00:06 switch-blade-stuff

I just noticed a type on the example code, updated the original comment

switch-blade-stuff avatar Jun 05 '21 00:06 switch-blade-stuff

Okay, it compiles and I repro the bug now. I think it's the same issue. You could try https://github.com/microsoft/vscode-cpptools/issues/1231#issuecomment-837528890 as a potential workaround.

sean-mcmanus avatar Jun 05 '21 01:06 sean-mcmanus

Since the original VS bug report got closed I have re-created it including the new example of using two partial specializations https://developercommunity.visualstudio.com/t/Intellisense:-template-and-incomplete-t/10113071?entry=problem&space=62&ftype=idea&preview2=true&q=intellisense+template+placeholder

Tradias avatar Aug 07 '22 18:08 Tradias

@Tradias Thanks. Yeah, they bulk-closed a bunch of issues as Low Priority and we didn't go through all of them to re-open them.

sean-mcmanus avatar Aug 08 '22 17:08 sean-mcmanus