即使任何构造函数都没有使用默认成员初始值设定项,在默认成员初始值设定项中使用仍然是 odr 使用吗?
例如,该程序是否格式错误,因为g<A>
使用了 odr,因此其定义被隐式实例化?
template<typename T>
void g() { sizeof(T); }
struct A;
struct B {
B() : i{} {};
int i = (&g<A>, 0);
};
int main() { }
Run Code Online (Sandbox Code Playgroud)
MSVC 认为不会。Clang、GCC 和 ICC 认为是的。https://godbolt.org/z/zrr9oEdfe
c++ one-definition-rule template-instantiation implicit-instantiation
template<typename T>
struct a
{
using type = int;
typename T::type i;
};
template<typename T, typename = a<T>>
void f1(T) {}
template<typename T, typename = typename a<T>::type>
void f2(T) {}
int main()
{
f1<int>(1); // ok
f2<int>(1); // error
return 0;
}
Run Code Online (Sandbox Code Playgroud)
实例化a<int>
应该是错误,因为它int::type
是非法的.但似乎f1<int>
不能引起实例化a<T>
,但f2<int>
可以.什么原因?
标题中的问题很清楚.更具体地说,请考虑以下示例:
#include <type_traits>
template <typename T>
struct is_complete_helper {
template <typename U>
static auto test(U*) -> std::integral_constant<bool, sizeof(U) == sizeof(U)>;
static auto test(...) -> std::false_type;
using type = decltype(test((T*)0));
};
template <typename T>
struct is_complete : is_complete_helper<T>::type {};
// The above is an implementation of is_complete from https://stackoverflow.com/a/21121104/5376789
template<class T> class X;
static_assert(!is_complete<X<char>>::type{});
// X<char> should be implicitly instantiated here, an incomplete type
template<class T> class X {};
static_assert(!is_complete<X<char>>::type{}); // #1
X<char> ch; // #2
Run Code Online (Sandbox Code Playgroud)
此代码与GCC和Clang编译.
c++ templates language-lawyer template-instantiation implicit-instantiation
我想编写一个M
接受不完整类型C
作为模板参数的类模板。但我也希望C
在最终定义时具有一些特征。
此代码是否有保证
template <auto> struct Dummy {};
template <typename C>
void check()
{
static_assert(std::is_trivial_v<C>);
}
template <typename C>
struct M : Dummy<&check<C>>
{
//static_assert(std::is_trivial_v<C>);//error: incomplete type
C * p;
};
struct Test;
M<Test> m;
int main()
{
return 0;
}
#if defined(FLAG)
struct Test {};
#else
struct Test { std::string non_trivial_member; };
#endif
Run Code Online (Sandbox Code Playgroud) c++ language-lawyer function-templates implicit-instantiation non-type-template-parameter